src/lib/subs/satmap.c

Go to the documentation of this file.
00001 /*
00002  *  Empire - A multi-player, client/server Internet based war game.
00003  *  Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
00004  *                           Ken Stevens, Steve McClure
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  *
00020  *  ---
00021  *
00022  *  See files README, COPYING and CREDITS in the root of the source
00023  *  tree for related information and legal notices.  It is expected
00024  *  that future projects/authors will amend these files as needed.
00025  *
00026  *  ---
00027  *
00028  *  satmap.c: Do a satellite map given an x,y location, effic and other
00029  * 
00030  *  Known contributors to this file:
00031  *     Steve McClure, 2000
00032  */
00033 
00034 #include <config.h>
00035 
00036 #include <stdlib.h>
00037 #include "file.h"
00038 #include "land.h"
00039 #include "map.h"
00040 #include "misc.h"
00041 #include "nat.h"
00042 #include "nsc.h"
00043 #include "optlist.h"
00044 #include "plane.h"
00045 #include "player.h"
00046 #include "prototypes.h"
00047 #include "sect.h"
00048 #include "ship.h"
00049 #include "xy.h"
00050 
00051 static char **rad;
00052 static char *radbuf;
00053 
00054 void
00055 satmap(int x, int y, int eff, int range, int flags, int type)
00056 {
00057     int acc;
00058     struct sctstr sect;
00059     struct shpstr ship;
00060     struct lndstr land;
00061     int count;
00062     struct nstr_item ni;
00063     struct nstr_sect ns;
00064     int rx, ry;
00065     int row;
00066     int n;
00067     int changed = 0;
00068     long crackle;
00069     signed char noise[100];
00070     char selection[1024];
00071 
00072     if (!eff)
00073         return;
00074 
00075     if (!radbuf)
00076         radbuf = malloc(WORLD_Y * (WORLD_X + 1));
00077     if (!rad) {
00078         rad = malloc(WORLD_Y * sizeof(char *));
00079         if (rad && radbuf) {
00080             for (rx = 0; rx < WORLD_Y; rx++)
00081                 rad[rx] = &radbuf[(WORLD_X + 1) * rx];
00082         }
00083     }
00084 
00085     if (!radbuf || !rad) {
00086         pr("Memory error in satmap, tell the deity.\n");
00087         return;
00088     }
00089 
00090     range = range * (eff / 100.0);
00091     pr("%s efficiency %d%%, max range %d\n",
00092        xyas(x, y, player->cnum), eff, range);
00093     memset(noise, 0, sizeof(noise));
00094     if (eff < 100) {
00095         pr("Some noise on the transmission...\n");
00096         for (n = 0; n < (100 - eff); ++n)
00097             noise[100 * n / (100 - eff)] = 1;
00098     }
00099 
00100     /* Have to convert to player coords, since it gets converted
00101        back from there */
00102     sprintf(selection, "@%s:%d", xyas(x, y, player->cnum), range);
00103 
00104     if (type == EF_BAD || type == EF_SECTOR) {
00105         if (type == EF_SECTOR)  /* Use ?conditionals */
00106             snxtsct(&ns, selection);
00107         else
00108             snxtsct_dist(&ns, x, y, range);
00109 
00110         blankfill(radbuf, &ns.range, 1);
00111         if (flags & P_S) {
00112             pr("Satellite sector report\n");
00113             prdate();
00114             sathead();
00115             acc = (flags & P_I) ? 5 : 50;
00116         }
00117         crackle = count = 0;
00118         while (nxtsct(&ns, &sect)) {
00119             if (++crackle == 100)
00120                 crackle = 0;
00121             if (noise[crackle])
00122                 continue;
00123             if (flags & P_S) {
00124                 if (sect.sct_own && sect.sct_own != player->cnum) {
00125                     satdisp_sect(&sect, acc);
00126                     ++count;
00127                     if (opt_HIDDEN)
00128                         setcont(player->cnum, sect.sct_own, FOUND_FLY);
00129                 }
00130             }
00131             if ((flags & P_I) ||
00132                 sect.sct_type == SCT_WATER || sect.sct_type == SCT_MOUNT) {
00133                 rad[ns.dy][ns.dx] = dchr[sect.sct_type].d_mnem;
00134             } else
00135                 rad[ns.dy][ns.dx] = '?';
00136             changed +=
00137                 map_set(player->cnum, ns.x, ns.y, rad[ns.dy][ns.dx], 0);
00138         }
00139         if (changed)
00140             writemap(player->cnum);
00141         if (flags & P_S)
00142             pr("  %d sectors\n\n", count);
00143     }
00144 
00145     if ((type == EF_BAD || type == EF_SHIP) &&
00146         (flags & P_S || flags & P_I)) {
00147         if (type == EF_SHIP)
00148             snxtitem(&ni, EF_SHIP, selection);
00149         else
00150             snxtitem_dist(&ni, EF_SHIP, x, y, range);
00151 
00152         crackle = count = 0;
00153         if (flags & P_S) {
00154             pr("Satellite ship report\n");
00155             prdate();
00156             pr(" own  shp# ship type                                  sector   eff\n");
00157         }
00158         while (nxtitem(&ni, &ship)) {
00159             if (ship.shp_own == 0)
00160                 continue;
00161             if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
00162                 ((flags & (P_S | P_I)) != (P_S | P_I)))
00163                 continue;
00164             if (++crackle == 100)
00165                 crackle = 0;
00166             if (noise[crackle])
00167                 continue;
00168             if (flags & P_S) {
00169                 pr("%4d %4d %-16.16s %-25.25s ",
00170                    ship.shp_own, ship.shp_uid,
00171                    mchr[(int)ship.shp_type].m_name, ship.shp_name);
00172                 prxy("%4d,%-4d ", ship.shp_x, ship.shp_y, player->cnum);
00173                 pr("%3d%%\n", ship.shp_effic);
00174                 ++count;
00175                 if (opt_HIDDEN)
00176                     setcont(player->cnum, ship.shp_own, FOUND_FLY);
00177             }
00178             /* If we are imaging *and* drawing the map */
00179             if ((flags & P_I) && (type == EF_BAD)) {
00180                 /* Figure out where to put the ship */
00181                 /* First, figure out the distance from the two */
00182                 rx = diffx((int)ship.shp_x, x);
00183                 ry = diffy((int)ship.shp_y, y);
00184                 /* Next, determine which direction to add it to the center */
00185                 /* We can only do this if imaging and we have gotten the center
00186                    up above by imaging the sectors. */
00187                 rx = deltax(x, ns.range.lx) + rx;
00188                 ry = deltay(y, ns.range.ly) + ry;
00189                 /* &~0x20 makes it a cap letter */
00190                 rad[ry][rx] = (*mchr[(int)ship.shp_type].m_name) & ~0x20;
00191             }
00192         }
00193         if (flags & P_S)
00194             pr("  %d ships\n\n", count);
00195     }
00196 
00197     if ((type == EF_BAD || type == EF_LAND) &&
00198         (flags & P_S || flags & P_I)) {
00199         if (type == EF_LAND)
00200             snxtitem(&ni, EF_LAND, selection);
00201         else
00202             snxtitem_dist(&ni, EF_LAND, x, y, range);
00203 
00204         crackle = count = 0;
00205         if (flags & P_S) {
00206             pr("Satellite unit report\n");
00207             prdate();
00208             pr(" own  lnd# unit type         sector   eff\n");
00209         }
00210         while (nxtitem(&ni, &land)) {
00211             if (land.lnd_own == 0)
00212                 continue;
00213             if (lchr[(int)land.lnd_type].l_flags & L_SPY)
00214                 continue;
00215             if (!chance(land.lnd_effic / 20.0))
00216                 continue;
00217             if (++crackle == 100)
00218                 crackle = 0;
00219             if (noise[crackle])
00220                 continue;
00221             if (flags & P_S) {
00222                 pr("%4d %4d %-16.16s ",
00223                    land.lnd_own, land.lnd_uid,
00224                    lchr[(int)land.lnd_type].l_name);
00225                 prxy("%4d,%-4d", land.lnd_x, land.lnd_y, player->cnum);
00226                 pr("%3d%%\n", land.lnd_effic);
00227                 ++count;
00228                 if (opt_HIDDEN)
00229                     setcont(player->cnum, land.lnd_own, FOUND_FLY);
00230             }
00231             /* If we are imaging *and* drawing the map */
00232             if ((flags & P_I) && (type == EF_BAD)) {
00233                 /* Figure out where to put the unit */
00234                 /* First, figure out the distance from the two */
00235                 rx = diffx((int)land.lnd_x, x);
00236                 ry = diffy((int)land.lnd_y, y);
00237                 /* Next, determine which direction to add it to the center */
00238                 /* We can only do this if imaging and we have gotten the center
00239                    up above by imaging the sectors. */
00240                 rx = deltax(x, ns.range.lx) + rx;
00241                 ry = deltay(y, ns.range.ly) + ry;
00242                 /* &~0x20 makes it a cap letter */
00243                 rad[ry][rx] = (*lchr[(int)land.lnd_type].l_name) & ~0x20;
00244             }
00245         }
00246         if (flags & P_S)
00247             pr("  %d units\n\n", count);
00248     }
00249 
00250     /* Ok, have we made the map?  If so, display it */
00251     if (type == EF_BAD) {
00252         /*
00253          * print out the map
00254          * We have to make the center a '0' for ve
00255          * ve needs a garbage line to terminate the map
00256          */
00257         rad[deltay(y, ns.range.ly)][deltax(x, ns.range.lx)] = '0';
00258 
00259         pr("Satellite radar report\n");
00260 #ifdef HAY
00261         /* This is wrong for small, hitech worlds. */
00262         n = deltay(ns.range.hy, ns.range.ly);
00263 #else
00264         /* This is already available, so why not use it. */
00265         n = ns.range.height;
00266 #endif
00267         for (row = 0; row < n; row++)
00268             pr("%s\n", rad[row]);
00269         pr("\n(c) 1989 Imaginative Images Inc.\n");
00270     }
00271 }
00272 
00273 void
00274 sathead(void)
00275 {
00276     pr("                    sct rd  rl  def\n");
00277     pr("   sect   type own  eff eff eff eff  civ  mil  shl  gun iron  pet  food\n");
00278 }
00279 
00280 void
00281 satdisp_sect(struct sctstr *sp, int acc)
00282 {
00283     prxy("%4d,%-4d   ", sp->sct_x, sp->sct_y, player->cnum);
00284     pr("%c  %3d  %3d %3d %3d %3d %4d %4d %4d %4d %4d %4d %5d\n",
00285        dchr[sp->sct_type].d_mnem,
00286        sp->sct_own, roundintby((int)sp->sct_effic, acc / 2),
00287        roundintby((int)sp->sct_road, acc / 2),
00288        roundintby((int)sp->sct_rail, acc / 2),
00289        roundintby((int)sp->sct_defense, acc / 2),
00290        roundintby(sp->sct_item[I_CIVIL], acc),
00291        roundintby(sp->sct_item[I_MILIT], acc),
00292        roundintby(sp->sct_item[I_SHELL], acc),
00293        roundintby(sp->sct_item[I_GUN], acc),
00294        roundintby(sp->sct_item[I_IRON], acc),
00295        roundintby(sp->sct_item[I_PETROL], acc),
00296        roundintby(sp->sct_item[I_FOOD], acc));
00297     map_set(player->cnum, sp->sct_x, sp->sct_y, dchr[sp->sct_type].d_mnem,
00298             0);
00299 }
00300 
00301 void
00302 satdisp_units(coord x, coord y)
00303 {
00304     int first;
00305     struct nstr_item ni;
00306     struct shpstr ship;
00307     struct lndstr land;
00308 
00309     snxtitem_xy(&ni, EF_SHIP, x, y);
00310     first = 1;
00311     while (nxtitem(&ni, &ship)) {
00312         if (ship.shp_own == 0)
00313             continue;
00314         if (mchr[(int)ship.shp_type].m_flags & M_SUB)
00315             continue;
00316         if (first) {
00317             pr("\t own  shp# ship type                                  sector   eff\n");
00318             first = 0;
00319         }
00320         pr("\t%4d %4d %-16.16s %-25.25s ",
00321            ship.shp_own, ship.shp_uid,
00322            mchr[(int)ship.shp_type].m_name, ship.shp_name);
00323         prxy("%4d,%-4d ", ship.shp_x, ship.shp_y, player->cnum);
00324         pr("%3d%%\n", ship.shp_effic);
00325     }
00326 
00327     if (!first)
00328         pr("\n");
00329 
00330     snxtitem_xy(&ni, EF_LAND, x, y);
00331     first = 1;
00332 
00333     while (nxtitem(&ni, &land)) {
00334         if (land.lnd_own == 0)
00335             continue;
00336         if (land.lnd_ship >= 0 || land.lnd_land >= 0)
00337             continue;
00338         if (lchr[(int)land.lnd_type].l_flags & L_SPY)
00339             continue;
00340         if (!chance(land.lnd_effic / 20.0))
00341             continue;
00342 
00343         if (first) {
00344             pr("\t own  lnd# unit type       sector   eff\n");
00345             first = 0;
00346         }
00347 
00348         pr("\t%4d %4d %-16.16s ",
00349            land.lnd_own, land.lnd_uid, lchr[(int)land.lnd_type].l_name);
00350         prxy("%4d,%-4d ", land.lnd_x, land.lnd_y, player->cnum);
00351         pr("%3d%%\n", land.lnd_effic);
00352     }
00353 
00354     if (!first)
00355         pr("\n");
00356 }

Generated on Fri Mar 28 11:01:15 2008 for empserver by  doxygen 1.5.2