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 #include <config.h>
00036
00037 #include "commands.h"
00038 #include "optlist.h"
00039 #include "ship.h"
00040
00041 #define TSIZE 200
00042
00043 struct coast {
00044 struct coast *c_next;
00045 int c_spotted;
00046 int c_number;
00047 struct shpstr c_shp;
00048 };
00049
00050 static int showship(struct coast **cpp, int x, int y);
00051
00052
00053
00054
00055 int
00056 coas(void)
00057 {
00058 struct sctstr sect;
00059 struct nstr_sect nstr;
00060 struct coast *cp;
00061 struct coast *list[TSIZE];
00062 int i, k, j, n;
00063 int vrange, see;
00064 int x, y;
00065 int mink, minj, maxk, maxj;
00066 int nship = 0;
00067 double tech;
00068 struct nstr_item ni;
00069
00070 if (!snxtsct(&nstr, player->argp[1]))
00071 return RET_SYN;
00072 for (i = 0; i < TSIZE; i++)
00073 list[i] = 0;
00074 cp = malloc(sizeof(*cp));
00075 snxtitem_all(&ni, EF_SHIP);
00076 while (nxtitem(&ni, &cp->c_shp)) {
00077 if (cp->c_shp.shp_own == 0 || cp->c_shp.shp_own == player->cnum)
00078 continue;
00079
00080
00081
00082
00083 getsect(cp->c_shp.shp_x, cp->c_shp.shp_y, §);
00084 if ((mchr[(int)cp->c_shp.shp_type].m_flags & M_SUB) &&
00085 (sect.sct_own != player->cnum))
00086 continue;
00087 n = scthash(cp->c_shp.shp_x, cp->c_shp.shp_y, TSIZE);
00088 cp->c_spotted = 0;
00089 cp->c_number = i;
00090 cp->c_next = list[n];
00091 list[n] = cp;
00092 cp = malloc(sizeof(*cp));
00093 nship++;
00094 }
00095
00096 free(cp);
00097 pr("- = [ Coastwatch report for %s ] = -\n", cname(player->cnum));
00098 pr(" Country Ship Location\n");
00099 tech = tfact(player->cnum, 1.0);
00100 while (nxtsct(&nstr, §) && nship) {
00101 if (sect.sct_own != player->cnum)
00102 continue;
00103 see = sect.sct_type == SCT_RADAR ? 14 : 4;
00104 vrange = (int)(sect.sct_effic / 100.0 * see * tech);
00105 if (vrange < 1)
00106 vrange = 1;
00107 maxk = vrange;
00108 maxj = vrange * 2;
00109 vrange *= vrange;
00110 mink = -maxk;
00111 minj = -maxj;
00112 for (j = minj; j <= maxj && nship; j++) {
00113 x = xnorm(sect.sct_x + j);
00114 for (k = mink; k <= maxk && nship; k++) {
00115 if ((j + k) & 01)
00116 continue;
00117
00118 if (vrange < (j * j + 3 * k * k) / 4)
00119 continue;
00120 y = ynorm(sect.sct_y + k);
00121 n = scthash(x, y, TSIZE);
00122 if (list[n] == 0)
00123 continue;
00124 nship -= showship(&list[n], x, y);
00125 }
00126 }
00127 }
00128
00129 for (i = 0; i < TSIZE; i++) {
00130 while (NULL != (cp = list[i])) {
00131 list[i] = cp->c_next;
00132 free(cp);
00133 }
00134 }
00135 return RET_OK;
00136 }
00137
00138 static int
00139 showship(struct coast **cpp, int x, int y)
00140 {
00141 struct coast *cp;
00142 struct coast *todelete = 0;
00143 struct coast **prev;
00144 int nship = 0;
00145
00146 prev = 0;
00147 cp = *cpp;
00148 prev = cpp;
00149 do {
00150
00151 if (todelete) {
00152 free(todelete);
00153 todelete = 0;
00154 }
00155 if (cp->c_shp.shp_x != x || cp->c_shp.shp_y != y) {
00156 prev = &(*prev)->c_next;
00157 continue;
00158 }
00159 pr(" %12.12s (#%3d) %s @ %s\n",
00160 cname(cp->c_shp.shp_own), cp->c_shp.shp_own,
00161 prship(&cp->c_shp), xyas(x, y, player->cnum));
00162 if (opt_HIDDEN) {
00163 setcont(player->cnum, cp->c_shp.shp_own, FOUND_COAST);
00164 }
00165 *prev = cp->c_next;
00166 todelete = cp;
00167 nship++;
00168 } while (NULL != (cp = cp->c_next));
00169
00170 if (todelete)
00171 free(todelete);
00172 return nship;
00173 }