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
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.
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.
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
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.
28 * move.c: Move something somewhere.
30 * Known contributors to this file:
47 #include "prototypes.h"
49 extern int move_map(s_char *what, coord curx, coord cury, s_char *arg);
52 move_ground(s_char *what, struct sctstr *start, struct sctstr *end, double mobility, double weight, s_char *path, int (*map) (s_char *, coord, coord, s_char *), int exploring, int *dam)
62 struct sctstr sect, ending_sect;
63 struct sctstr next, dsect;
65 coord curx, cury, oldx, oldy;
68 s_char *movstr, *BestLandPath(s_char *, struct sctstr *, struct sctstr *, double *, int);
74 int takedam = (*dam), out=0;
83 if (path && sarg_xy(path, &dx, &dy) && getsect(dx,dy,&ending_sect)){
84 if ((ending_sect.sct_x == start->sct_x) &&
85 (ending_sect.sct_y == start->sct_y)){
86 pr("Start sector is ending sector!\n");
89 pr("Looking for best path to %s\n", path);
90 path = BestLandPath(buf2, start, &ending_sect, &total_mcost, MOB_ROAD);
91 if (exploring && (path != (s_char *)0)) /* take off the 'h' */
92 *(path+strlen(path)-1) = '\0';
93 if (path == (s_char *)0)
94 pr("No owned path exists!\n");
96 pr("Using best path '%s', movement cost %1.3f\n",
99 bcopy(path,bpath,strlen(path));
102 if ((total_mcost*weight) > mobility){
103 pr("Not enough mobility to go all the way. Nothing moved.\n");
114 if (getsect(curx, cury, §) < 0) {
115 logerror("move_path: getsect %d,%d", curx, cury);
123 if (movstr == 0 || *movstr == 0) {
125 map(what, curx, cury, (s_char *)0); }
127 move_map(what, curx, cury, (s_char *)0); }
128 sprintf(prompt, "<%.1f: %c %s> ", mobility,
129 dchr[sect.sct_type].d_mnem,
130 xyas(sect.sct_x, sect.sct_y, player->cnum));
131 movstr = getstring(prompt, buf);
133 if (movstr && sarg_xy(movstr, &dx, &dy)){
134 if (getsect(dx,dy,&dsect)){
135 movstr=BestLandPath(buf2,§,&dsect,&mv_cost,MOB_ROAD);
137 pr("Invalid destination sector!\n");
141 if (movstr == (s_char *)0){
142 pr("Can't get to %s from here!\n",
143 xyas(dx,dy,player->cnum));
146 if ((mv_cost*weight) > mobility){
147 pr("Not enough mobility to go all the way. Nothing moved.\n");
148 movstr = (s_char *)0;
150 pr("Using best path '%s', movement cost %1.3f\n",
153 bcopy(movstr,bpath,strlen(movstr));
158 if (movstr == 0 || *movstr == 0)
160 if ((dir = chkdir(*movstr, DIR_STOP, DIR_MAP)) < 0) {
161 pr("\"%c\" is not legal...", *movstr);
162 direrr("'%c' to stop ", "'%c' to view ",
168 if (dir == DIR_MAP) {
170 map(what, curx, cury, movstr+1);
173 } else if (dir == DIR_STOP)
175 else if (dir == DIR_VIEW) {
176 pr("%d%% %s with %d civilians.\n", sect.sct_effic,
177 dchr[sect.sct_type].d_name,
178 getvar(V_CIVIL, (s_char *)§, EF_SECTOR));
182 * now see if we can move into the
183 * next sector. Mobility, terrain,
184 * or ownership may prevent us.
186 tmpx += diroff[dir][0];
187 tmpy += diroff[dir][1];
188 if (getsect(tmpx, tmpy, &next) < 0) {
189 pr("You can't go there...\n");
194 if ((next.sct_type == SCT_SANCT) &&
195 (next.sct_own != player->cnum)) {
196 pr("Converts, huh?\n");
198 intcost = (int) total_mcost;
199 if (chance(total_mcost - intcost))
203 getvec(VT_ITEM, vec, (s_char *)&next, EF_SECTOR);
204 sect_mcost = sector_mcost(&next, MOB_ROAD);
205 if ((!player->owner && (!exploring ||
206 (vec[I_MILIT] || vec[I_CIVIL]))) ||
207 sect_mcost == -1.0) {
208 /* already-owned, or prohibited terrain */
209 pr("You can't go there...\n");
213 sect_mcost *= weight;
214 if (sect_mcost > mobility) {
215 pr("Not enough mobility. ");
216 pr("You can't go there...\n");
220 mobility -= sect_mcost;
221 total_mcost += sect_mcost;
225 if (cury != start->sct_y)
227 if (curx != start->sct_x)
233 *dam += check_lmines(sect.sct_x, sect.sct_y, weight);
237 * Check and see if anyone will interdict us
239 if (takedam && chance(weight/100.0) &&
240 ((curx != oldx) || (cury != oldy)))
241 (*dam) += ground_interdict(curx,cury,player->cnum,"commodities");
246 intcost = (int) total_mcost;
249 if ((start->sct_x == end->sct_x) && (start->sct_y == end->sct_y) && !out)
252 if (chance(total_mcost - intcost))
260 move_map(s_char *what, coord curx, coord cury, s_char *arg)
272 np = getnatp(player->cnum);
273 rel_x = xrel(np, curx);
274 rel_y = yrel(np, cury);
275 sprintf(range, "%d:%d,%d:%d", rel_x-2, rel_x+2, rel_y-1, rel_y+1);
277 /* This is necessary, otherwise move_map would attempt to pay */
278 /* attention to the conditional arguments left behind by such */
279 /* a command as "tran p -1,-1 ?eff=100".. It'd then only see */
280 /* 100% efficienct sects, and get all screwed up --ts */
281 if (!snxtsct(&ns, range))
284 while (i < 7 && nxtsct(&ns, §)) {
285 view[i] = dchr[sect.sct_type].d_mnem;
286 switch (sect.sct_type) {
294 if (sect.sct_own != player->cnum && !player->god)
298 changed += map_set(player->cnum, ns.x, ns.y, view[i], 0);
302 writemap(player->cnum);
303 if (!getsect(curx, cury, §))
305 getvec(VT_ITEM, vec, (s_char *)§, EF_SECTOR);
306 pr(" %c %c eff mob civ mil uw food work avail\n",
308 pr(" %c %c %c %3d %3d %4d %4d %4d %4d %3d %3d\n",
309 view[2], view[3], view[4],
310 sect.sct_effic, sect.sct_mobil, vec[I_CIVIL],vec[I_MILIT],
311 vec[I_UW],vec[I_FOOD], sect.sct_work, sect.sct_avail);
312 pr(" %c %c\n", view[5], view[6]);
317 fly_map(coord curx, coord cury)
327 np = getnatp(player->cnum);
328 rel_x = xrel(np, curx);
329 rel_y = yrel(np, cury);
330 sprintf(range, "%d:%d,%d:%d", rel_x-2, rel_x+2, rel_y-1, rel_y+1);
332 /* This is necessary, otherwise move_map would attempt to pay */
333 /* attention to the conditional arguments left behind by such */
334 /* a command as "tran p -1,-1 ?eff=100".. It'd then only see */
335 /* 100% efficienct sects, and get all screwed up --ts */
337 if (!snxtsct(&ns, range))
340 while (i < 7 && nxtsct(&ns, §)){
341 if (!(view[i] = player->bmap[sctoff(ns.x, ns.y)]))
346 pr(" %c %c\n",view[0], view[1]);
347 pr(" %c %c %c\n", view[2], view[3], view[4]);
348 pr(" %c %c\n", view[5], view[6]);
353 check_lmines(coord x, coord y, double weight)
359 getsect(x, y, §);
360 mines = getvar(V_MINE, (s_char *)§, EF_SECTOR);
362 sect.sct_oldown != player->cnum &&
363 chance(DMINE_LHITCHANCE(mines)) &&
364 chance(weight/100.0)) {
366 pr("Blammo! Landmines detected! in %s ",
367 xyas(sect.sct_x,sect.sct_y,player->cnum));
370 putvar(V_MINE, mines, (s_char *)§, EF_SECTOR);
372 pr("%d damage sustained.\n", dam);