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 != V_MILIT) {
101 snxtitem_xy(&ni, EF_LAND, sect.sct_x, sect.sct_y);
102 while (nxtitem(&ni, (s_char *)&land)) {
103 if (land.lnd_own == player->cnum)
104 tot_mil += total_mil(&land);
106 if ((sect.sct_item[I_MILIT] + tot_mil) * 10 < sect.sct_item[I_CIVIL]) {
107 pr("Military control required to move goods.\n");
111 stype = sect.sct_type;
113 infected = sect.sct_pstage == PLG_INFECT;
114 amt_src = sect.sct_item[vtype];
115 if (!istest && amt_src <= 0) {
116 pr("No %s in %s\n", ip->i_name,
117 xyas(sect.sct_x, sect.sct_y, player->cnum));
121 mob = (int)sect.sct_mobil;
122 if (!istest && vtype == V_CIVIL && sect.sct_oldown != own) {
123 pr("You can't move conquered populace!\n");
127 pr("No mobility in %s\n",
128 xyas(sect.sct_x, sect.sct_y, player->cnum));
131 if (vtype == V_CIVIL) {
132 work = sect.sct_work;
134 pr("Warning: civil unrest\n");
135 loyal = sect.sct_loyal;
136 } else if (vtype == V_MILIT) {
141 sprintf(prompt, "Number of %s to test move? ", ip->i_name);
143 sprintf(prompt, "Number of %s to move? (max %d) ",
144 ip->i_name, amt_src);
145 if ((amount = onearg(player->argp[3], prompt)) < 0)
147 if (!check_sect_ok(§))
149 if (amount > amt_src) {
151 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);
154 pr("Only moving %d.\n", amount);
158 if (!want_to_abandon(§, vtype, amount, 0)) {
159 pr("Move cancelled.\n");
163 if (!check_sect_ok(§))
168 packing = ip->i_pkg[dp->d_pkg];
169 if (packing > 1 && sect.sct_effic < 60)
171 weight = (double)amount *ip->i_lbs / packing;
173 * First remove commodities from source sector
176 getsect(x, y, &start);
177 if (start.sct_own != player->cnum) {
178 pr("Somebody has captured that sector!\n");
181 amt_src = start.sct_item[vtype];
182 if (amt_src < amount) {
183 pr("Only %d %s left in %s!\n", amt_src,
184 ip->i_name, xyas(start.sct_x, start.sct_y, player->cnum));
190 start.sct_item[vtype] = amt_src;
191 start.sct_flags |= MOVE_IN_PROGRESS;
196 * Now parse the path and return ending sector.
198 dam = (istest ? 0 : 1);
199 if (dam && !chance(weight / 200.0))
201 mcost = move_ground((s_char *)ip, §, &endsect,
202 weight, player->argp[4],
203 cmd_move_map, 0, &dam);
206 left = commdamage(amount, dam, ip->i_vtype);
209 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));
211 pr("All of the %s you were moving were destroyed!\n",
219 pr("Total movement cost = %d\n", mcost);
221 pr("No mobility used\n");
225 pr("Move aborted\n");
226 getsect(x, y, §);
227 sect.sct_mobil = (u_char)mob;
229 } else if (!istest) {
231 * decrement mobility appropriately.
233 getsect(x, y, &start);
234 mob = start.sct_mobil;
240 start.sct_mobil = (u_char)mob;
241 left = start.sct_mobil;
243 getsect(endsect.sct_x, endsect.sct_y, §);
247 * Check for lotsa stuff
249 if (sect.sct_own != player->cnum) {
250 if (sect.sct_own != 0)
251 pr("Somebody has captured that sector!\n");
252 getsect(x, y, §);
254 if (vtype == V_CIVIL && sect.sct_item[I_CIVIL]
255 && sect.sct_oldown != player->cnum) {
256 pr("Your civilians don't want to stay!\n");
257 getsect(x, y, §);
260 amt_dst = sect.sct_item[vtype];
261 if (32767 - amt_dst < amount) {
262 pr("Only enough room for %d in %s. The goods will be returned.\n",
263 32767 - amt_dst, xyas(sect.sct_x, sect.sct_y, player->cnum));
264 getsect(x, y, §);
268 pr("%d mob left in %s\n", left,
269 xyas(start.sct_x, start.sct_y, player->cnum));
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 (32767 - amt_dst < amount)
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 (32767 - amt_dst < amount) {
312 amount = 32767 - 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 == V_CIVIL) {
327 sect.sct_loyal = ((amt_dst * sect.sct_loyal) +
328 (amount * loyal)) / (amt_dst + amount);
329 sect.sct_work = ((amt_dst * sect.sct_work) +
330 (amount * work)) / (amt_dst + amount);
331 } else { /* ! NEW_WORK */
333 /* It only takes one bad apple... */
334 if (sect.sct_loyal < loyal)
335 sect.sct_loyal = loyal;
336 if (sect.sct_work > work)
337 sect.sct_work = work;
341 getsect(x, y, &start);
342 start.sct_flags &= ~MOVE_IN_PROGRESS;
348 * Pretty tacky, but it works.
349 * If more commands start doing this, then
350 * rewrite map to do the right thing.
352 /* I think this is no longer used, check subs/move.c:move_ground() */
355 cmd_move_map(s_char *what, coord curx, coord cury, s_char *arg)
357 player->argp[1] = arg;
358 player->argp[2] = "";
359 player->argp[3] = "";
360 player->argp[4] = "";
361 player->argp[5] = "";
367 want_to_abandon(struct sctstr *sp, int vtype, int amnt, struct lndstr *lp)
371 /* First, would we be abandoning it? If not, just return that it's
373 if (!would_abandon(sp, vtype, amnt, lp))
376 sprintf(prompt, "Do you really want to abandon %s [yn]? ",
377 xyas(sp->sct_x, sp->sct_y, player->cnum));
379 /* now, if they say yes that it's ok, just return 1 */
388 would_abandon(struct sctstr *sp, int vtype, int amnt, struct lndstr *lp)
390 int mil, civs, loyalcivs;
392 if ((vtype != V_CIVIL) && (vtype != V_MILIT))
395 mil = sp->sct_item[I_MILIT];
396 civs = sp->sct_item[I_CIVIL];
398 if (vtype == V_MILIT)
401 if (vtype == V_CIVIL)
404 if (sp->sct_own == sp->sct_oldown)
409 /* If they have a military unit there, they still own it */
411 && ((loyalcivs == 0) && (mil == 0)
412 && (has_units(sp->sct_x, sp->sct_y, sp->sct_own, lp) == 0)))