/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
- * Ken Stevens, Steve McClure
+ * Copyright (C) 1986-2021, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Ken Stevens, Steve McClure, Markus Armbruster
*
- * This program is free software; you can redistribute it and/or modify
+ * Empire is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
+ * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* ---
*
- * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- * related information and legal notices. It is expected that any future
- * projects/authors will amend these files as needed.
+ * See files README, COPYING and CREDITS in the root of the source
+ * tree for related information and legal notices. It is expected
+ * that future projects/authors will amend these files as needed.
*
* ---
*
* tran.c: Transport nuclear devices and planes
- *
+ *
* Known contributors to this file:
* Steve McClure, 2000
- *
+ * Markus Armbruster, 2006-2016
*/
#include <config.h>
-#include <string.h>
-#include "misc.h"
-#include "player.h"
-#include "sect.h"
+#include "commands.h"
+#include "map.h"
#include "nuke.h"
-#include "xy.h"
-#include "nsc.h"
#include "plane.h"
-#include "ship.h"
-#include "file.h"
-#include "nat.h"
-#include "land.h"
-#include "commands.h"
-static int tran_map(s_char *what, coord curx, coord cury, s_char *arg);
+static int tran_pmap(coord, coord, char *, char *);
+static int tran_nmap(coord, coord, char *, char *);
static int tran_nuke(void);
static int tran_plane(void);
+static int pln_weight(struct plnstr *);
int
-tran(void)
+c_transport(void)
{
- s_char *what;
- s_char buf[1024];
+ char *what;
+ char buf[1024];
- what =
- getstarg(player->argp[1], "transport what (nuke or plane): ", buf);
- if (what == 0)
+ what = getstarg(player->argp[1], "transport what (nuke or plane): ",
+ buf);
+ if (!what)
return RET_SYN;
if (*what == 'n')
return tran_nuke();
return RET_SYN;
}
-/*
- * Kinda silly; only moves the first nuke.
- * Maybe nukes should be made into commodities?
- */
static int
tran_nuke(void)
{
- struct nchrstr *ncp;
- coord x, y;
+ coord srcx, srcy;
coord dstx, dsty;
- int found;
- s_char *p;
- int nuketype;
- int moving;
+ int mcost;
+ int weight, count;
+ int type, dam;
+ struct nstr_item nstr;
struct nukstr nuke;
struct sctstr sect;
struct sctstr endsect;
- int mcost, dam;
- struct nstr_item nstr;
- s_char buf[1024];
- if (!(p = getstarg(player->argp[2], "from sector : ", buf)))
- return RET_SYN;
- if (!sarg_xy(p, &x, &y))
+ weight = 0;
+ count = 0;
+ if (!snxtitem(&nstr, EF_NUKE, player->argp[2], NULL))
return RET_SYN;
- if (!getsect(x, y, §) || !player->owner) {
- pr("Not yours\n");
- return RET_FAIL;
- }
- snxtitem_xy(&nstr, EF_NUKE, sect.sct_x, sect.sct_y);
- found = 0;
while (nxtitem(&nstr, &nuke)) {
- if (player->owner) {
- found = 1;
- break;
+ if (!player->owner)
+ continue;
+ type = nuke.nuk_type;
+ if (nuke.nuk_plane >= 0) {
+ pr("%s is armed and can't be transported\n", prnuke(&nuke));
+ return RET_FAIL;
}
+ if (count == 0) {
+ srcx = nuke.nuk_x;
+ srcy = nuke.nuk_y;
+ } else {
+ if (nuke.nuk_x != srcx || nuke.nuk_y != srcy) {
+ pr("All nukes must be in the same sector.\n");
+ return RET_FAIL;
+ }
+ }
+ weight += nchr[type].n_weight;
+ ++count;
}
- if (!found) {
- pr("There are no nukes in %s\n",
- xyas(sect.sct_x, sect.sct_y, player->cnum));
- return RET_FAIL;
- }
- if (!(p = getstarg(player->argp[3], "warhead type : ", buf)))
- return RET_SYN;
- if (!check_sect_ok(§))
- return RET_FAIL;
- nuketype = typematch(p, EF_NUKE);
- if (nuketype < 0) {
- pr("No such nuke type!\n");
- return RET_SYN;
- }
- ncp = &nchr[nuketype];
- if (!nuke.nuk_types[nuketype]) {
- pr("No %s nukes in %s\n",
- ncp->n_name, xyas(sect.sct_x, sect.sct_y, player->cnum));
+ if (count == 0) {
+ pr("No nukes\n");
return RET_FAIL;
}
- p = getstarg(player->argp[4], "number of warheads : ", buf);
- if (!check_sect_ok(§))
- return RET_FAIL;
- if (p == 0 || *p == 0 || (moving = atoi(p)) < 0)
+ if (!getsect(srcx, srcy, §) || !player->owner) {
+ pr("You don't own %s\n", xyas(srcx, srcy, player->cnum));
return RET_FAIL;
- if (moving > nuke.nuk_types[nuketype]) {
- moving = nuke.nuk_types[nuketype];
- if (moving)
- pr("only moving %d\n", moving);
- else
- return RET_FAIL;
}
if (!military_control(§)) {
pr("Military control required to move nukes.\n");
return RET_FAIL;
}
dam = 0;
- mcost = move_ground((s_char *)&nuke, §, &endsect,
- (double)ncp->n_weight * moving,
- player->argp[5], tran_map, 0, &dam);
-
+ mcost = move_ground(§, &endsect, weight,
+ player->argp[3], tran_nmap, 0, &dam);
if (mcost < 0)
return 0;
+ dstx = endsect.sct_x;
+ dsty = endsect.sct_y;
+ snxtitem_rewind(&nstr);
+ while (nxtitem(&nstr, &nuke)) {
+ if (!player->owner)
+ continue;
+ /* TODO apply dam */
+ nuke.nuk_x = dstx;
+ nuke.nuk_y = dsty;
+ nuke.nuk_mission = 0;
+ putnuke(nuke.nuk_uid, &nuke);
+ }
if (mcost > 0)
pr("Total movement cost = %d\n", mcost);
else
pr("No mobility used\n");
-
- dstx = endsect.sct_x;
- dsty = endsect.sct_y;
- /*
- * decrement mobility from src sector
- */
- getsect(nuke.nuk_x, nuke.nuk_y, §);
- sect.sct_mobil -= mcost;
- if (sect.sct_mobil < 0)
+ getsect(srcx, srcy, §);
+ if (sect.sct_mobil >= mcost)
+ sect.sct_mobil -= mcost;
+ else
sect.sct_mobil = 0;
putsect(§);
- /*
- * update old nuke
- */
- if (!getnuke(nuke.nuk_uid, &nuke)) {
- pr("Could not find that stockpile again.\n");
- return RET_FAIL;
- }
- if (nuke.nuk_types[nuketype] < moving || nuke.nuk_own != player->cnum) {
- pr("Stockpile changed!\n");
- return RET_FAIL;
- }
- nuk_delete(&nuke, nuketype, moving);
- nuk_add(dstx, dsty, nuketype, moving);
return RET_OK;
}
static int
tran_plane(void)
{
- int srcx, srcy;
- int dstx, dsty;
+ coord srcx, srcy;
+ coord dstx, dsty;
int mcost;
int weight, count;
- int type, dam;
+ int dam;
struct nstr_item nstr;
struct plnstr plane;
struct sctstr sect;
weight = 0;
count = 0;
- if (!snxtitem(&nstr, EF_PLANE, player->argp[2]))
+ if (!snxtitem(&nstr, EF_PLANE, player->argp[2], NULL))
return RET_SYN;
/*
* First do some sanity checks: make sure that they are all in the,
while (nxtitem(&nstr, &plane)) {
if (!player->owner)
continue;
- type = plane.pln_type;
if (plane.pln_ship >= 0) {
- pr("%s is at sea and can't be transported\n", prplane(&plane));
+ pr("%s is stowed on ship #%d, and can't be transported\n",
+ prplane(&plane), plane.pln_ship);
+ return RET_FAIL;
+ } else if (plane.pln_land >= 0) {
+ pr("%s is stowed on land #%d, and can't be transported\n",
+ prplane(&plane), plane.pln_land);
return RET_FAIL;
} else if (plane.pln_harden != 0) {
pr("%s has been hardened and can't be transported\n",
prplane(&plane));
return RET_FAIL;
- } else if ((plane.pln_flags & PLN_LAUNCHED) &&
- (plchr[type].pl_flags & P_O)) {
+ } else if (pln_is_in_orbit(&plane)) {
pr("%s is in space and can't be transported\n",
prplane(&plane));
return RET_FAIL;
return RET_FAIL;
}
}
- weight += plchr[type].pl_lcm + (plchr[type].pl_hcm * 2);
+ weight += pln_weight(&plane);
++count;
}
if (count == 0) {
return RET_FAIL;
}
dam = 1;
- mcost = move_ground((s_char *)&plane, §, &endsect,
- (double)weight,
- player->argp[3], tran_map, 0, &dam);
+ mcost = move_ground(§, &endsect, weight,
+ player->argp[3], tran_pmap, 0, &dam);
dam /= count;
if (mcost < 0)
return 0;
else
pr("No mobility used\n");
getsect(srcx, srcy, §);
- sect.sct_mobil -= mcost;
- if (sect.sct_mobil < 0)
+ if (sect.sct_mobil >= mcost)
+ sect.sct_mobil -= mcost;
+ else
sect.sct_mobil = 0;
putsect(§);
return RET_OK;
}
+static int
+pln_weight(struct plnstr *pp)
+{
+ int w, i;
+
+ w = 0;
+ for (i = I_NONE + 1; i <= I_MAX; i++)
+ w += plchr[pp->pln_type].pl_mat[i] * ichr[i].i_lbs;
+ return w;
+}
+
/*
* Pretty tacky, but it works.
* If more commands start doing this, then
* rewrite map to do the right thing.
*/
-/* I think this is no longer used, check subs/move.c:move_ground() */
/*ARGSUSED*/
static int
-tran_map(s_char *what, coord curx, coord cury, s_char *arg)
+tran_pmap(coord curx, coord cury, char *arg1, char *arg2)
+{
+ return display_region_map(0, EF_PLANE, curx, cury, arg1, arg2);
+}
+
+static int
+tran_nmap(coord curx, coord cury, char *arg1, char *arg2)
{
- player->argp[1] = arg;
- player->condarg = 0;
- return map();
+ return display_region_map(0, EF_NUKE, curx, cury, arg1, arg2);
}