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 #include <config.h>
00035
00036 #include <ctype.h>
00037 #include "damage.h"
00038 #include "file.h"
00039 #include "map.h"
00040 #include "path.h"
00041 #include "player.h"
00042 #include "prototypes.h"
00043 #include "sect.h"
00044
00045 static int move_map(coord curx, coord cury, char *arg);
00046
00047 int
00048 move_ground(struct sctstr *start, struct sctstr *end,
00049 double weight, char *path,
00050 int (*map)(coord, coord, char *), int exploring,
00051 int *dam)
00052 {
00053 struct sctstr sect, ending_sect;
00054 struct sctstr next, dsect;
00055 coord curx, cury, oldx, oldy;
00056 coord tmpx, tmpy;
00057 coord dx, dy;
00058 char *movstr;
00059 double sect_mcost;
00060 double total_mcost;
00061 double mv_cost;
00062 double mobility = start->sct_mobil;
00063 int dir;
00064 int intcost;
00065 int takedam = *dam;
00066 int out = 0;
00067 char bpath[512];
00068 char buf2[512];
00069 char prompt[128];
00070 char buf[1024];
00071
00072 *end = *start;
00073 if (mobility <= 0.0)
00074 return -1;
00075 *dam = 0;
00076 if (path && sarg_xy(path, &dx, &dy) && getsect(dx, dy, &ending_sect)) {
00077 if ((ending_sect.sct_x == start->sct_x) &&
00078 (ending_sect.sct_y == start->sct_y)) {
00079 pr("Start sector is ending sector!\n");
00080 return -1;
00081 }
00082 pr("Looking for best path to %s\n", path);
00083 path = BestLandPath(buf2, start, &ending_sect, &total_mcost,
00084 MOB_MOVE);
00085 if (exploring && path)
00086 path[strlen(path) - 1] = '\0';
00087 if (!path)
00088 pr("No owned path exists!\n");
00089 else {
00090 pr("Using best path '%s', movement cost %1.3f\n",
00091 path, total_mcost);
00092 strncpy(bpath, path, sizeof(bpath));
00093 path = bpath;
00094 }
00095 if ((total_mcost * weight) > mobility) {
00096 pr("Not enough mobility to go all the way. Nothing moved.\n");
00097 return -1;
00098 }
00099 }
00100 movstr = path;
00101 curx = start->sct_x;
00102 cury = start->sct_y;
00103 total_mcost = 0.0;
00104 if (getsect(curx, cury, §) < 0) {
00105 logerror("move_path: getsect %d,%d", curx, cury);
00106 return -1;
00107 }
00108 for (;;) {
00109 oldx = curx;
00110 oldy = cury;
00111 if (!movstr || *movstr == 0) {
00112 if (exploring) {
00113 map(curx, cury, NULL);
00114 } else {
00115 move_map(curx, cury, NULL);
00116 }
00117 sprintf(prompt, "<%.1f: %c %s> ", mobility,
00118 dchr[sect.sct_type].d_mnem,
00119 xyas(sect.sct_x, sect.sct_y, player->cnum));
00120 movstr = getstring(prompt, buf);
00121 }
00122 if (movstr && sarg_xy(movstr, &dx, &dy)) {
00123 if (getsect(dx, dy, &dsect)) {
00124 movstr = BestLandPath(buf2, §, &dsect, &mv_cost,
00125 MOB_MOVE);
00126 } else {
00127 pr("Invalid destination sector!\n");
00128 movstr = NULL;
00129 }
00130
00131 if (movstr == NULL) {
00132 pr("Can't get to %s from here!\n",
00133 xyas(dx, dy, player->cnum));
00134 } else {
00135 if ((mv_cost * weight) > mobility) {
00136 pr("Not enough mobility to go all the way. Nothing moved.\n");
00137 movstr = NULL;
00138 } else {
00139 pr("Using best path '%s', movement cost %1.3f\n",
00140 movstr, mv_cost);
00141 strncpy(bpath, movstr, sizeof(bpath));
00142 movstr = bpath;
00143 }
00144 }
00145 }
00146 if (!movstr || *movstr == 0) {
00147 buf2[0] = dirch[DIR_STOP];
00148 buf2[1] = 0;
00149 movstr = buf2;
00150 }
00151 if ((dir = chkdir(*movstr, DIR_STOP, DIR_MAP)) < 0) {
00152 pr("\"%c\" is not legal...", *movstr);
00153 direrr("'%c' to stop ", "'%c' to view ", "& '%c' to map\n");
00154 *movstr = 0;
00155 continue;
00156 }
00157 do movstr++; while (isspace(*movstr));
00158 if (dir == DIR_MAP) {
00159 if (!exploring)
00160 map(curx, cury, movstr);
00161 *movstr = 0;
00162 continue;
00163 } else if (dir == DIR_STOP)
00164 break;
00165 else if (dir == DIR_VIEW) {
00166 pr("%d%% %s with %d civilians.\n", sect.sct_effic,
00167 dchr[sect.sct_type].d_name, sect.sct_item[I_CIVIL]);
00168 continue;
00169 }
00170
00171
00172
00173
00174
00175 tmpx = curx + diroff[dir][0];
00176 tmpy = cury + diroff[dir][1];
00177 if (getsect(tmpx, tmpy, &next) < 0) {
00178 pr("You can't go there...\n");
00179 *movstr = 0;
00180 continue;
00181 }
00182 if (!player->god) {
00183 if ((next.sct_type == SCT_SANCT) &&
00184 (next.sct_own != player->cnum)) {
00185 pr("Converts, huh?\n");
00186 *movstr = 0;
00187 continue;
00188 }
00189 sect_mcost = sector_mcost(&next, MOB_MOVE);
00190 if ((!player->owner && (!exploring
00191 || next.sct_item[I_MILIT]
00192 || next.sct_item[I_CIVIL]))
00193 || sect_mcost == -1.0) {
00194
00195 pr("You can't go there...\n");
00196 *movstr = 0;
00197 continue;
00198 }
00199 sect_mcost *= weight;
00200 if (sect_mcost > mobility) {
00201 pr("Not enough mobility. ");
00202 pr("You can't go there...\n");
00203 *movstr = 0;
00204 continue;
00205 }
00206 mobility -= sect_mcost;
00207 total_mcost += sect_mcost;
00208 }
00209 curx = tmpx;
00210 cury = tmpy;
00211 if (cury != start->sct_y)
00212 out = 1;
00213 if (curx != start->sct_x)
00214 out = 1;
00215
00216 sect = next;
00217
00218 if (takedam)
00219 *dam += check_lmines(sect.sct_x, sect.sct_y, weight);
00220 if (*dam >= 100)
00221 break;
00222
00223
00224
00225 if (takedam && chance(weight / 100.0) &&
00226 ((curx != oldx) || (cury != oldy)))
00227 *dam += ground_interdict(curx, cury, player->cnum,
00228 "commodities");
00229 if (*dam >= 100)
00230 break;
00231 }
00232 *end = sect;
00233 intcost = (int)total_mcost;
00234 if (intcost < 0)
00235 return -1;
00236 if ((start->sct_x == end->sct_x) && (start->sct_y == end->sct_y)
00237 && !out)
00238 return -1;
00239
00240 if (chance(total_mcost - intcost))
00241 intcost++;
00242 return intcost;
00243 }
00244
00245
00246
00247 static int
00248 move_map(coord curx, coord cury, char *arg)
00249 {
00250 struct nstr_sect ns;
00251 struct sctstr sect;
00252 char view[7];
00253 int i;
00254 int changed = 0;
00255
00256 snxtsct_dist(&ns, curx, cury, 1);
00257 i = 0;
00258 while (i < 7 && nxtsct(&ns, §)) {
00259
00260 view[i] = dchr[sect.sct_type].d_mnem;
00261 switch (sect.sct_type) {
00262 case SCT_WATER:
00263 case SCT_RURAL:
00264 case SCT_MOUNT:
00265 case SCT_WASTE:
00266 case SCT_PLAINS:
00267 break;
00268 default:
00269 if (sect.sct_own != player->cnum && !player->god)
00270 view[i] = '?';
00271 break;
00272 }
00273 changed += map_set(player->cnum, ns.x, ns.y, view[i], 0);
00274 i++;
00275 }
00276 if (changed)
00277 writemap(player->cnum);
00278 if (!getsect(curx, cury, §))
00279 return RET_FAIL;
00280 pr(" %c %c eff mob civ mil uw food work avail\n",
00281 view[0], view[1]);
00282 pr(" %c %c %c %3d %3d %4d %4d %4d %4d %3d %3d\n",
00283 view[2], view[3], view[4],
00284 sect.sct_effic, sect.sct_mobil,
00285 sect.sct_item[I_CIVIL], sect.sct_item[I_MILIT], sect.sct_item[I_UW],
00286 sect.sct_item[I_FOOD], sect.sct_work, sect.sct_avail);
00287 pr(" %c %c\n", view[5], view[6]);
00288 return RET_OK;
00289 }
00290
00291 int
00292 fly_map(coord curx, coord cury)
00293 {
00294 struct nstr_sect ns;
00295 struct sctstr sect;
00296 char view[7];
00297 int i;
00298
00299 snxtsct_dist(&ns, curx, cury, 1);
00300 i = 0;
00301 while (i < 7 && nxtsct(&ns, §)) {
00302
00303 if (!(view[i] = player->bmap[sctoff(ns.x, ns.y)]))
00304 view[i] = ' ';
00305 i++;
00306 }
00307
00308 pr(" %c %c\n", view[0], view[1]);
00309 pr(" %c %c %c\n", view[2], view[3], view[4]);
00310 pr(" %c %c\n", view[5], view[6]);
00311 return RET_OK;
00312 }
00313
00314 int
00315 check_lmines(coord x, coord y, double weight)
00316 {
00317 struct sctstr sect;
00318 int dam = 0;
00319
00320 getsect(x, y, §);
00321 if (sect.sct_mines > 0 &&
00322 sect.sct_oldown != player->cnum &&
00323 chance(DMINE_LHITCHANCE(sect.sct_mines)) && chance(weight / 100.0)) {
00324 pr_beep();
00325 pr("Blammo! Landmines detected! in %s ",
00326 xyas(sect.sct_x, sect.sct_y, player->cnum));
00327 dam = roll(20);
00328 --sect.sct_mines;
00329 putsect(§);
00330 pr("%d damage sustained.\n", dam);
00331 }
00332 return dam;
00333 }