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 commodities around
30 * Known contributors to this file:
49 static int cmd_move_map(s_char *what, coord curx, coord cury, s_char *arg);
56 struct sctstr endsect;
81 istest = *player->argp[0] == 't';
82 if ((ip = whatitem(player->argp[1], "move what? ")) == 0)
85 if (!(p = getstarg(player->argp[2], "from sector : ", buf)))
87 if (!sarg_xy(p, &x, &y))
89 if (!getsect(x, y, §) || !player->owner) {
94 * military control necessary to move
95 * goodies in occupied territory.
97 if (!istest && sect.sct_oldown != player->cnum && vtype != I_MILIT) {
98 if (!military_control(§)) {
99 pr("Military control required to move goods.\n");
103 stype = sect.sct_type;
105 infected = sect.sct_pstage == PLG_INFECT;
106 amt_src = sect.sct_item[vtype];
107 if (!istest && amt_src <= 0) {
108 pr("No %s in %s\n", ip->i_name,
109 xyas(sect.sct_x, sect.sct_y, player->cnum));
113 mob = (int)sect.sct_mobil;
114 if (!istest && vtype == I_CIVIL && sect.sct_oldown != own) {
115 pr("You can't move conquered populace!\n");
119 pr("No mobility in %s\n",
120 xyas(sect.sct_x, sect.sct_y, player->cnum));
123 if (vtype == I_CIVIL) {
124 work = sect.sct_work;
126 pr("Warning: civil unrest\n");
127 loyal = sect.sct_loyal;
128 } else if (vtype == I_MILIT) {
133 sprintf(prompt, "Number of %s to test move? ", ip->i_name);
135 sprintf(prompt, "Number of %s to move? (max %d) ",
136 ip->i_name, amt_src);
137 if ((amount = onearg(player->argp[3], prompt)) < 0)
139 if (!check_sect_ok(§))
141 if (amount > amt_src) {
143 pr("Note: there are actually only %d %s in %s,\nbut the test will be made for %d %s as you requested.\n", amt_src, ip->i_name, xyas(sect.sct_x, sect.sct_y, player->cnum), amount, ip->i_name);
146 pr("Only moving %d.\n", amount);
150 if (!istest && !want_to_abandon(§, vtype, amount, 0)) {
151 pr("Move cancelled.\n");
155 if (!check_sect_ok(§))
160 packing = ip->i_pkg[dp->d_pkg];
161 if (packing > 1 && sect.sct_effic < 60)
163 weight = (double)amount *ip->i_lbs / packing;
165 * First remove commodities from source sector
168 getsect(x, y, &start);
169 if (start.sct_own != player->cnum) {
170 pr("Somebody has captured that sector!\n");
173 amt_src = start.sct_item[vtype];
174 if (amt_src < amount) {
175 pr("Only %d %s left in %s!\n", amt_src,
176 ip->i_name, xyas(start.sct_x, start.sct_y, player->cnum));
182 start.sct_item[vtype] = amt_src;
183 start.sct_flags |= MOVE_IN_PROGRESS;
188 * Now parse the path and return ending sector.
190 dam = (istest ? 0 : 1);
191 if (dam && !chance(weight / 200.0))
193 mcost = move_ground((s_char *)ip, §, &endsect,
194 weight, player->argp[4],
195 cmd_move_map, 0, &dam);
198 left = commdamage(amount, dam, ip->i_vtype);
201 pr("%d of the %s you were moving were destroyed!\nOnly %d %s made it to %s\n", amount - left, ip->i_name, left, ip->i_name, xyas(endsect.sct_x, endsect.sct_y, player->cnum));
203 pr("All of the %s you were moving were destroyed!\n",
211 pr("Total movement cost = %d\n", mcost);
213 pr("No mobility used\n");
217 pr("Move aborted\n");
218 getsect(x, y, §);
219 sect.sct_mobil = (u_char)mob;
221 } else if (!istest) {
223 * decrement mobility appropriately.
225 getsect(x, y, &start);
226 mob = start.sct_mobil;
232 start.sct_mobil = (u_char)mob;
233 left = start.sct_mobil;
235 getsect(endsect.sct_x, endsect.sct_y, §);
239 * Check for lotsa stuff
241 if (sect.sct_own != player->cnum) {
242 if (sect.sct_own != 0)
243 pr("Somebody has captured that sector!\n");
244 getsect(x, y, §);
246 if (vtype == I_CIVIL && sect.sct_item[I_CIVIL]
247 && sect.sct_oldown != player->cnum) {
248 pr("Your civilians don't want to stay!\n");
249 getsect(x, y, §);
252 amt_dst = sect.sct_item[vtype];
253 if (amount > ITEM_MAX - amt_dst) {
254 pr("Only enough room for %d in %s. The goods will be returned.\n",
255 ITEM_MAX - amt_dst, xyas(sect.sct_x, sect.sct_y, player->cnum));
256 /* FIXME Not nice. Move what we can and return the rest. */
257 getsect(x, y, §);
261 pr("%d mob left in %s\n", left,
262 xyas(start.sct_x, start.sct_y, player->cnum));
265 getsect(x, y, &start);
266 start.sct_flags &= ~MOVE_IN_PROGRESS;
271 /* If the sector that things are going to is no longer
272 owned by the player, and was the starting sector,
273 try to find somewhere to dump the stuff. If nowhere
274 to dump it, it disappears. */
275 if (sect.sct_own != player->cnum && sect.sct_x == x && sect.sct_y == y) {
276 pr("Can't return the goods, since the starting point is no longer\n");
277 pr("owned by you.\n");
278 /* First lets see if there is one with room */
279 for (n = DIR_FIRST; n <= DIR_LAST; n++) {
280 getsect(x + diroff[n][0], y + diroff[n][1], &tsct);
281 if (tsct.sct_own != player->cnum)
283 amt_dst = tsct.sct_item[vtype];
284 if (amount > ITEM_MAX - amt_dst)
290 /* Find any sector if none with room */
291 for (n = DIR_FIRST; n <= DIR_LAST; n++) {
292 getsect(x + diroff[n][0], y + diroff[n][1], &tsct);
293 if (tsct.sct_own != player->cnum)
299 pr("The goods had nowhere to go, and were destroyed.\n");
300 sect.sct_flags &= ~MOVE_IN_PROGRESS;
305 pr("The goods were dumped into %s.\n",
306 xyas(tsct.sct_x, tsct.sct_y, player->cnum));
307 getsect(tsct.sct_x, tsct.sct_y, §);
310 amt_dst = sect.sct_item[vtype];
311 if (amount > ITEM_MAX - amt_dst) {
312 amount = ITEM_MAX - amt_dst;
313 pr("Only room for %d, the rest were lost.\n", amount);
317 sect.sct_item[vtype] = amount + amt_dst;
319 * Now add commodities to destination sector,
320 * along with plague that came along for the ride.
321 * Takeover unowned sectors if not deity.
323 if (infected && sect.sct_pstage == PLG_HEALTHY)
324 sect.sct_pstage = PLG_EXPOSED;
325 if (vtype == I_CIVIL) {
327 = (amt_dst * sect.sct_loyal + amount * loyal) / (amt_dst + amount);
329 = (amt_dst * sect.sct_work + amount * work) / (amt_dst + amount);
332 getsect(x, y, &start);
333 start.sct_flags &= ~MOVE_IN_PROGRESS;
339 * Pretty tacky, but it works.
340 * If more commands start doing this, then
341 * rewrite map to do the right thing.
343 /* I think this is no longer used, check subs/move.c:move_ground() */
346 cmd_move_map(s_char *what, coord curx, coord cury, s_char *arg)
348 player->argp[1] = arg;
349 player->argp[2] = "";
350 player->argp[3] = "";
351 player->argp[4] = "";
352 player->argp[5] = "";
358 want_to_abandon(struct sctstr *sp, int vtype, int amnt, struct lndstr *lp)
362 /* First, would we be abandoning it? If not, just return that it's
364 if (!would_abandon(sp, vtype, amnt, lp))
367 sprintf(prompt, "Do you really want to abandon %s [yn]? ",
368 xyas(sp->sct_x, sp->sct_y, player->cnum));
370 /* now, if they say yes that it's ok, just return 1 */
379 would_abandon(struct sctstr *sp, int vtype, int amnt, struct lndstr *lp)
381 int mil, civs, loyalcivs;
383 if ((vtype != I_CIVIL) && (vtype != I_MILIT))
386 mil = sp->sct_item[I_MILIT];
387 civs = sp->sct_item[I_CIVIL];
389 if (vtype == I_MILIT)
392 if (vtype == I_CIVIL)
395 if (sp->sct_own == sp->sct_oldown)
400 /* If they have a military unit there, they still own it */
402 && ((loyalcivs == 0) && (mil == 0)
403 && (has_units(sp->sct_x, sp->sct_y, sp->sct_own, lp) == 0)))