/*
* 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-2012, 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/>.
*
* ---
*
* ---
*
* load.c: load/unload goods from a sector onto a ship or land unit
- *
+ *
* Known contributors to this file:
* David Sharnoff, 1987
* Ken Stevens, 1995 (rewritten)
* Steve McClure, 1998-2000
+ * Markus Armbruster, 2004-2011
*/
#include <config.h>
-#include <string.h>
-#include "misc.h"
-#include "player.h"
-#include "xy.h"
-#include "file.h"
-#include "plague.h"
-#include "sect.h"
-#include "ship.h"
-#include "plane.h"
-#include "land.h"
+#include <ctype.h>
+#include "commands.h"
#include "item.h"
-#include "nsc.h"
-#include "nat.h"
+#include "land.h"
#include "optlist.h"
-#include "commands.h"
+#include "plague.h"
+#include "plane.h"
+#include "ship.h"
+#include "unit.h"
/*
* The values 1 and -1 are important below, don't change them.
*/
-#define LOAD 1
-#define UNLOAD -1
+#define LOAD 1
+#define UNLOAD -1
static int load_plane_ship(struct sctstr *sectp, struct shpstr *sp,
int noisy, int load_unload, int *nshipsp);
struct sctstr sect;
struct shpstr ship;
int retval;
- s_char *p;
- s_char buf[1024];
+ char *p;
+ char buf[1024];
- if (!(p = getstarg(player->argp[1],
- "What commodity (or 'plane' or 'land')? ", buf))
- || !*p)
+ p = getstarg(player->argp[1],
+ "What commodity (or 'plane' or 'land')? ", buf);
+ if (!p || !*p)
return RET_SYN;
if (!strncmp(p, "plane", 5))
return RET_SYN;
}
- if (!(p = getstarg(player->argp[2], "Ship(s): ", buf)) || !*p)
+ p = getstarg(player->argp[2], "Ship(s): ", buf);
+ if (!p || !*p)
return RET_SYN;
noisy = isdigit(*p);
- if (!snxtitem(&nbst, EF_SHIP, p))
+ if (!snxtitem(&nbst, EF_SHIP, p, NULL))
return RET_SYN;
load_unload = **player->argp == 'l' ? LOAD : UNLOAD;
while (nxtitem(&nbst, &ship)) {
if (!ship.shp_own)
continue;
- if (!player->owner && (load_unload == UNLOAD)) {
- continue;
- }
- if (opt_MARKET) {
- if (ontradingblock(EF_SHIP, &ship)) {
- pr("You cannot load/unload an item on the trading block!\n");
+ if (!player->owner) {
+ if (load_unload == UNLOAD || !noisy)
continue;
- }
- }
-
- if (ship.shp_own != player->cnum) {
- if (!noisy)
- continue;
- if (getrel(getnatp(player->cnum), ship.shp_own) < FRIENDLY)
+ if (relations_with(ship.shp_own, player->cnum) < FRIENDLY)
continue;
}
+
if (!getsect(ship.shp_x, ship.shp_y, §)) /* XXX */
continue;
- if ((sect.sct_own != player->cnum) &&
- (ship.shp_own != player->cnum))
- continue;
- if (!player->owner &&
- !sect_has_dock(§))
- continue;
if (!sect.sct_own)
continue;
- if ((sect.sct_own != player->cnum) && (load_unload == LOAD)) {
- if (noisy)
- pr("You don't own %s \n",
- xyas(ship.shp_x, ship.shp_y, player->cnum));
- continue;
+ if (!player->owner) {
+ if (ship.shp_own != player->cnum)
+ continue;
+ if (!sect_has_dock(§))
+ continue;
+ if (load_unload == LOAD) {
+ if (noisy)
+ pr("You don't own %s \n",
+ xyas(sect.sct_x, sect.sct_y, player->cnum));
+ continue;
+ }
}
if (!sect_has_dock(§)) {
if (noisy)
- pr("Sector %s is not a harbor%s%s.\n",
- xyas(ship.shp_x, ship.shp_y, player->cnum),
- dchr[SCT_CAPIT].d_nav == NAV_CANAL ? " or a " : "",
- dchr[SCT_CAPIT].d_nav == NAV_CANAL ?
- dchr[SCT_CAPIT].d_name : "");
+ pr("Sector %s is not a harbor or canal.\n",
+ xyas(sect.sct_x, sect.sct_y, player->cnum));
continue;
}
- if (sect.sct_own != player->cnum && load_unload == UNLOAD
- && getrel(getnatp(sect.sct_own), player->cnum) < FRIENDLY) {
+ if (load_unload == UNLOAD
+ && !player->owner
+ && relations_with(sect.sct_own, player->cnum) < FRIENDLY) {
if (noisy)
pr("You can't unload into an unfriendly %s\n",
dchr[sect.sct_type].d_name);
if (noisy)
pr("The %s at %s is not 2%% efficient yet.\n",
dchr[sect.sct_type].d_name,
- xyas(ship.shp_x, ship.shp_y, player->cnum));
+ xyas(sect.sct_x, sect.sct_y, player->cnum));
continue;
}
+
+ if (opt_MARKET) {
+ if (ontradingblock(EF_SHIP, &ship)) {
+ pr("You cannot load/unload an item on the trading block!\n");
+ continue;
+ }
+ }
+
switch (type) {
case EF_PLANE:
- if (0 !=
- (retval =
- load_plane_ship(§, &ship, noisy, load_unload,
- &nships)))
+ retval = load_plane_ship(§, &ship, noisy, load_unload,
+ &nships);
+ if (retval != 0)
return retval;
break;
case EF_LAND:
- if (0 !=
- (retval =
- load_land_ship(§, &ship, noisy, load_unload,
- &nships)))
+ retval = load_land_ship(§, &ship, noisy, load_unload,
+ &nships);
+ if (retval != 0)
return retval;
break;
case EF_SECTOR:
- if (0 !=
- (retval =
- load_comm_ship(§, &ship, ich, load_unload, &nships)))
+ retval = load_comm_ship(§, &ship, ich, load_unload,
+ &nships);
+ if (retval != 0)
return retval;
}
/* load/unload plague */
struct sctstr sect;
struct lndstr land;
int retval;
- s_char *p;
- s_char buf[1024];
+ char *p;
+ char buf[1024];
- if (!(p = getstarg(player->argp[1],
- "What commodity (or 'plane' or 'land')? ", buf))
- || !*p)
+ p = getstarg(player->argp[1],
+ "What commodity (or 'plane' or 'land')? ", buf);
+ if (!p || !*p)
return RET_SYN;
if (!strncmp(p, "plane", 5))
type = EF_PLANE;
return RET_SYN;
}
- if (!(p = getstarg(player->argp[2], "Unit(s): ", buf)) || !*p)
+ p = getstarg(player->argp[2], "Unit(s): ", buf);
+ if (!p || !*p)
return RET_SYN;
noisy = isdigit(*p);
- if (!snxtitem(&nbst, EF_LAND, p))
+ if (!snxtitem(&nbst, EF_LAND, p, NULL))
return RET_SYN;
- load_unload = *(*player->argp + 1) == 'l' ? LOAD : UNLOAD;
+ load_unload = player->argp[0][1] == 'l' ? LOAD : UNLOAD;
nunits = 0;
while (nxtitem(&nbst, &land)) {
if (land.lnd_own == 0)
continue;
-
- if (player->cnum != land.lnd_own &&
- getrel(getnatp(player->cnum), land.lnd_own) != ALLIED)
- continue;
+ if (!player->owner) {
+ if (load_unload == UNLOAD || !noisy)
+ continue;
+ if (relations_with(land.lnd_own, player->cnum) != ALLIED)
+ continue;
+ }
if (!getsect(land.lnd_x, land.lnd_y, §)) /* XXX */
continue;
+ if (!player->owner) {
+ if (land.lnd_own != player->cnum)
+ continue;
+ if (load_unload == LOAD) {
+ if (noisy)
+ pr("Sector %s is not yours.\n",
+ xyas(sect.sct_x, sect.sct_y, player->cnum));
+ continue;
+ }
+ if (relations_with(sect.sct_own, player->cnum) != ALLIED) {
+ pr("Sector %s is not yours.\n",
+ xyas(sect.sct_x, sect.sct_y, player->cnum));
+ continue;
+ }
+ }
- if (sect.sct_own != player->cnum && land.lnd_own != player->cnum)
- continue;
if (opt_MARKET) {
if (ontradingblock(EF_LAND, &land)) {
pr("You cannot load/unload an item on the trading block!\n");
}
}
- if (sect.sct_own != player->cnum &&
- getrel(getnatp(sect.sct_own), land.lnd_own) != ALLIED) {
- pr("Sector %s is not yours.\n",
- xyas(land.lnd_x, land.lnd_y, player->cnum));
- continue;
- }
switch (type) {
case EF_LAND:
- if (0 !=
- (retval =
- load_land_land(§, &land, noisy, load_unload,
- &nunits)))
+ retval = load_land_land(§, &land, noisy, load_unload,
+ &nunits);
+ if (retval != 0)
return retval;
break;
case EF_PLANE:
- if (0 !=
- (retval =
- load_plane_land(§, &land, noisy, load_unload,
- &nunits)))
+ retval = load_plane_land(§, &land, noisy, load_unload,
+ &nunits);
+ if (retval != 0)
return retval;
break;
case EF_SECTOR:
- if (0 !=
- (retval =
- load_comm_land(§, &land, ich, load_unload, &nunits)))
+ retval = load_comm_land(§, &land, ich, load_unload,
+ &nunits);
+ if (retval != 0)
return retval;
}
/* load/unload plague */
return RET_OK;
}
-void
-gift(natid givee, natid giver, void *ptr, int type, char *mesg)
+static int
+move_amount(int sect_amt, int unit_amt, int unit_max,
+ int load_unload, int amount)
{
- char *p;
+ int move_amt;
+
+ if (amount < 0)
+ move_amt = -amount - unit_amt;
+ else
+ move_amt = load_unload == LOAD ? amount : -amount;
+ if (move_amt > unit_max - unit_amt)
+ move_amt = unit_max - unit_amt;
+ if (move_amt < -unit_amt)
+ move_amt = -unit_amt;
+ if (move_amt > sect_amt)
+ move_amt = sect_amt;
+ if (move_amt < sect_amt - ITEM_MAX)
+ move_amt = sect_amt - ITEM_MAX;
+ return move_amt;
+}
- if (giver == givee)
- return;
-
- switch (type) {
- case EF_SHIP:
- p = prship(ptr);
- break;
- case EF_PLANE:
- p = prplane(ptr);
- break;
- case EF_LAND:
- p = prland(ptr);
- break;
- default:
- CANT_REACH();
- p = "a red herring";
+static int
+load_comm_ok(struct sctstr *sectp, natid unit_own,
+ i_type item, int move_amt)
+{
+ if (!move_amt)
+ return 0;
+ if (move_amt < 0 && !player->god && unit_own != player->cnum)
+ return 0;
+ if (move_amt > 0 && !player->god && sectp->sct_own != player->cnum)
+ return 0;
+ if (sectp->sct_oldown != unit_own && item == I_CIVIL) {
+ pr("%s civilians refuse to %s at %s!\n",
+ (move_amt < 0 ? unit_own : sectp->sct_oldown) == player->cnum
+ ? "Your" : "Foreign",
+ move_amt < 0 ? "disembark" : "board",
+ xyas(sectp->sct_x, sectp->sct_y, player->cnum));
+ return 0;
}
+ return 1;
+}
- wu(0, givee, "%s %s %s\n", cname(giver), p, mesg);
+void
+gift(natid givee, natid giver, void *ptr, char *mesg)
+{
+ if (giver != givee)
+ wu(0, givee, "%s %s %s\n", cname(giver), unit_nameof(ptr), mesg);
+ unit_give_away(ptr, givee, 0);
}
static int
struct nstr_item ni;
struct plnstr pln;
int loaded = 0;
- s_char buf[1024];
- s_char *p;
- s_char prompt[512];
+ char buf[1024];
+ char *p;
+ char prompt[512];
struct mchrstr *mcp = mchr + sp->shp_type;
- if (!(mcp->m_flags & (M_CHOPPER | M_XLIGHT | M_FLY | M_MSL))) {
+ if (mcp->m_nplanes + mcp->m_nchoppers + mcp->m_nxlight == 0) {
if (noisy)
pr("%s cannot carry planes\n", prship(sp));
return 0;
}
- count_planes(sp);
if (load_unload == LOAD &&
- sp->shp_nchoppers >= mcp->m_nchoppers &&
- sp->shp_nxlight >= mcp->m_nxlight &&
- sp->shp_nplane >= mcp->m_nplanes) {
+ shp_nplane(sp, NULL, NULL, NULL)
+ >= mcp->m_nchoppers + mcp->m_nxlight + mcp->m_nplanes) {
if (noisy)
pr("%s doesn't have room for any more planes\n", prship(sp));
return 0;
}
sprintf(prompt, "Plane(s) to %s %s? ",
load_unload == LOAD ? "load onto" : "unload from", prship(sp));
- if (!snxtitem(&ni, EF_PLANE,
- p = getstarg(player->argp[3], prompt, buf)))
+ p = getstarg(player->argp[3], prompt, buf);
+ if (!p)
+ return RET_SYN;
+ if (!snxtitem(&ni, EF_PLANE, p, NULL))
return RET_SYN;
if (!still_ok_ship(sectp, sp))
return RET_SYN;
- if (p && *p)
- noisy &= isdigit(*p);
+ if (noisy && p && *p)
+ noisy = isdigit(*p);
while (nxtitem(&ni, &pln)) {
- if (pln.pln_own != player->cnum)
+ if (!player->owner)
continue;
if (!(plchr[(int)pln.pln_type].pl_flags & P_L)
&& !(plchr[(int)pln.pln_type].pl_flags & P_E)
prplane(&pln), pln.pln_land);
continue;
}
+ if (pln.pln_harden != 0) {
+ if (noisy)
+ pr("%s has been hardened and can't be loaded\n",
+ prplane(&pln));
+ continue;
+ }
- /* Plane sanity done */
- /* Find the right ship */
if (load_unload == UNLOAD) {
if (pln.pln_ship != sp->shp_uid)
continue;
} else if (sp->shp_x != pln.pln_x || sp->shp_y != pln.pln_y)
continue;
- /* ship to (plane or missle) sanity */
- if (!can_be_on_ship(pln.pln_uid, sp->shp_uid)) {
- if (plchr[(int)pln.pln_type].pl_flags & P_L) {
- strcpy(buf, "planes");
- } else if (plchr[(int)pln.pln_type].pl_flags & P_K) {
- strcpy(buf, "choppers");
- } else if (plchr[(int)pln.pln_type].pl_flags & P_M) {
- strcpy(buf, "missiles");
- } else if (plchr[(int)pln.pln_type].pl_flags & P_E) {
- strcpy(buf, "extra light planes");
- } /* else impossible */
- if (noisy)
- pr("%s cannot carry %s.\n", prship(sp), buf);
+ if (!could_be_on_ship(&pln, sp, 0, 0, 0, 0)) {
+ if (noisy) {
+ if (plchr[(int)pln.pln_type].pl_flags & P_K)
+ p = "choppers";
+ else if (plchr[(int)pln.pln_type].pl_flags & P_E)
+ p = "extra light planes";
+ else if (plchr[(int)pln.pln_type].pl_flags & P_M)
+ p = "missiles";
+ else
+ p = "planes";
+ pr("%s cannot carry %s.\n", prship(sp), p);
+ }
continue;
}
/* Fit plane on ship */
}
sprintf(buf, "loaded on your %s at %s",
prship(sp), xyas(sp->shp_x, sp->shp_y, sp->shp_own));
- gift(sp->shp_own, player->cnum, &pln, EF_PLANE, buf);
- makelost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
- pln.pln_own = sp->shp_own;
- makenotlost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
- pln.pln_mission = 0;
+ gift(sp->shp_own, player->cnum, &pln, buf);
putplane(pln.pln_uid, &pln);
} else {
- if (!take_plane_off_ship(&pln, sp)) {
- pr("Unable to take plane off ship!\n");
- logerror("load: plane %d could not be taken off ship %d\n",
- pln.pln_uid, sp->shp_uid);
- continue;
- }
+ pln.pln_ship = -1;
sprintf(buf, "unloaded in your %s at %s",
dchr[sectp->sct_type].d_name,
xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
- gift(sectp->sct_own, player->cnum, &pln, EF_PLANE, buf);
- makelost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
- pln.pln_own = sectp->sct_own;
- makenotlost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
+ gift(sectp->sct_own, player->cnum, &pln, buf);
putplane(pln.pln_uid, &pln);
}
pr("%s %s %s at %s.\n",
load_land_ship(struct sctstr *sectp, struct shpstr *sp, int noisy,
int load_unload, int *nshipsp)
{
- struct nstr_item pni, ni;
+ struct nstr_item ni;
struct lndstr land;
- struct plnstr plane;
int loaded = 0;
- s_char *p;
- s_char prompt[512];
- s_char buf[1024];
+ char *p;
+ char prompt[512];
+ char buf[1024];
int load_spy = 0;
- count_units(sp);
if (load_unload == LOAD) {
- if (opt_LANDSPIES) {
- if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
- (mchr[(int)sp->shp_type].m_nland == 0)) {
- if (sp->shp_nland >= 2) {
- pr("Non-land unit carrying subs can only carry up to two spy units.\n");
- return 0;
- }
- /* Eh, let 'em load a spy only */
- load_spy = 1;
+ if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
+ (mchr[(int)sp->shp_type].m_nland == 0)) {
+ if (shp_nland(sp) >= 2) {
+ pr("Non-land unit carrying subs can only carry up to two spy units.\n");
+ return 0;
}
+ /* Eh, let 'em load a spy only */
+ load_spy = 1;
}
- if ((!load_spy) &&
- (sp->shp_nland >= mchr[(int)sp->shp_type].m_nland)) {
+ if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) {
if (noisy) {
if (mchr[(int)sp->shp_type].m_nland)
pr("%s doesn't have room for any more land units!\n",
}
sprintf(prompt, "Land unit(s) to %s %s? ",
load_unload == LOAD ? "load onto" : "unload from", prship(sp));
- if (!snxtitem(&ni, EF_LAND,
- p = getstarg(player->argp[3], prompt, buf)))
+ p = getstarg(player->argp[3], prompt, buf);
+ if (!p)
+ return RET_SYN;
+ if (!snxtitem(&ni, EF_LAND, p, NULL))
return RET_SYN;
if (!still_ok_ship(sectp, sp))
return RET_SYN;
- if (p && *p)
- noisy &= isdigit(*p);
+ if (noisy && p && *p)
+ noisy = isdigit(*p);
while (nxtitem(&ni, &land)) {
- if (land.lnd_own != player->cnum)
+ if (!player->owner)
continue;
if (load_unload == LOAD) {
prland(&land), land.lnd_land);
continue;
}
- lnd_count_units(&land);
- if (land.lnd_nland > 0) {
+ if (lnd_first_on_land(&land) >= 0) {
if (noisy)
pr("%s cannot be loaded since it is carrying units\n",
prland(&land));
}
/* Fit unit on ship */
if (load_unload == LOAD) {
- count_units(sp);
/* We have to check again, since it may have changed */
- if (opt_LANDSPIES) {
- if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
- (mchr[(int)sp->shp_type].m_nland == 0)) {
- if (sp->shp_nland >= 2) {
- pr("Non-land unit carrying subs can only carry up to two spy units.\n");
- return 0;
- }
- /* Eh, let 'em load a spy only */
- load_spy = 1;
+ if ((mchr[(int)sp->shp_type].m_flags & M_SUB) &&
+ (mchr[(int)sp->shp_type].m_nland == 0)) {
+ if (shp_nland(sp) >= 2) {
+ pr("Non-land unit carrying subs can only carry up to two spy units.\n");
+ return 0;
}
+ /* Eh, let 'em load a spy only */
+ load_spy = 1;
}
- if (!load_spy &&
- (sp->shp_nland >= mchr[(int)sp->shp_type].m_nland)) {
+ if (!load_spy && shp_nland(sp) >= mchr[sp->shp_type].m_nland) {
if (noisy) {
if (mchr[(int)sp->shp_type].m_nland)
pr("%s doesn't have room for any more land units!\n",
}
sprintf(buf, "loaded on your %s at %s",
prship(sp), xyas(sp->shp_x, sp->shp_y, sp->shp_own));
- gift(sp->shp_own, player->cnum, &land, EF_LAND, buf);
- makelost(EF_LAND, land.lnd_own, land.lnd_uid, land.lnd_x,
- land.lnd_y);
- land.lnd_own = sp->shp_own;
- makenotlost(EF_LAND, land.lnd_own, land.lnd_uid, land.lnd_x,
- land.lnd_y);
+ gift(sp->shp_own, player->cnum, &land, buf);
land.lnd_ship = sp->shp_uid;
land.lnd_harden = 0;
- land.lnd_mission = 0;
- resupply_all(&land);
- sp->shp_nland++;
putland(land.lnd_uid, &land);
- if (!has_supply(&land))
+#if 0
+ /*
+ * FIXME if this supplies from the sector, the putsect in
+ * load() / lload() duplicates those supplies, causing a
+ * seqno mismatch
+ */
+ if (!lnd_supply_all(&land))
pr("WARNING: %s is out of supply!\n", prland(&land));
- putship(sp->shp_uid, sp);
- snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
- while (nxtitem(&pni, &plane)) {
- if (plane.pln_flags & PLN_LAUNCHED)
- continue;
- if (plane.pln_land != land.lnd_uid)
- continue;
- sprintf(buf, "loaded on %s", prship(sp));
- gift(sp->shp_own, player->cnum, &plane, EF_PLANE, buf);
- makelost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_own = sp->shp_own;
- makenotlost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_mission = 0;
- putplane(plane.pln_uid, &plane);
- }
+#else
+ if (!lnd_in_supply(&land))
+ pr("WARNING: %s is out of supply!\n", prland(&land));
+#endif
} else {
sprintf(buf, "unloaded in your %s at %s",
dchr[sectp->sct_type].d_name,
xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
/* Spies are unloaded quietly, others aren't */
- if (!(lchr[(int)land.lnd_type].l_flags & L_SPY)) {
- gift(sectp->sct_own, player->cnum, &land, EF_LAND, buf);
- makelost(EF_LAND, land.lnd_own, land.lnd_uid,
- land.lnd_x, land.lnd_y);
- land.lnd_own = sectp->sct_own;
- makenotlost(EF_LAND, land.lnd_own, land.lnd_uid,
- land.lnd_x, land.lnd_y);
- }
-
+ if (!(lchr[(int)land.lnd_type].l_flags & L_SPY))
+ gift(sectp->sct_own, player->cnum, &land, buf);
land.lnd_ship = -1;
- sp->shp_nland--;
putland(land.lnd_uid, &land);
- putship(sp->shp_uid, sp);
-
- /* Spies are unloaded quietly, others aren't, and
- in the off chance they can carry a plane (missile?)
- they are quietly unloaded too. */
- if (!(lchr[(int)land.lnd_type].l_flags & L_SPY)) {
- snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
- while (nxtitem(&pni, &plane)) {
- if (plane.pln_flags & PLN_LAUNCHED)
- continue;
- if (plane.pln_land != land.lnd_uid)
- continue;
- sprintf(buf, "unloaded at %s",
- xyas(plane.pln_x, plane.pln_y,
- sectp->sct_own));
- gift(sectp->sct_own, player->cnum, &plane, EF_PLANE, buf);
- makelost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_own = sectp->sct_own;
- makenotlost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_mission = 0;
- putplane(plane.pln_uid, &plane);
- }
- }
}
pr("%s %s %s at %s.\n",
prland(&land),
{
i_type item = ich->i_uid;
struct mchrstr *mcp = &mchr[(int)sp->shp_type];
- int ship_amt, ship_max, sect_amt, move_amt;
- int amount;
- s_char prompt[512];
- s_char *p;
- s_char buf[1024];
+ int ship_amt, sect_amt, move_amt;
+ char prompt[512];
+ char *p;
+ char buf[1024];
sprintf(prompt, "Number of %s to %s %s at %s? ",
ich->i_name,
(load_unload == UNLOAD) ?
"unload from" : "load onto",
prship(sp), xyas(sp->shp_x, sp->shp_y, player->cnum));
- if (!(p = getstarg(player->argp[3], prompt, buf)) || !*p)
+ p = getstarg(player->argp[3], prompt, buf);
+ if (!p || !*p)
return RET_SYN;
if (!still_ok_ship(sectp, sp))
return RET_SYN;
ship_amt = sp->shp_item[item];
- ship_max = mcp->m_item[item];
sect_amt = sectp->sct_item[item];
- amount = atoi(p);
- if (amount < 0)
- move_amt = -amount - ship_amt;
- else
- move_amt = load_unload == LOAD ? amount : -amount;
- if (move_amt > ship_max - ship_amt)
- move_amt = ship_max - ship_amt;
- if (move_amt < -ship_amt)
- move_amt = -ship_amt;
- if (move_amt > sect_amt)
- move_amt = sect_amt;
- if (move_amt < sect_amt - ITEM_MAX)
- move_amt = sect_amt - ITEM_MAX;
- if (!move_amt)
+ move_amt = move_amount(sect_amt, ship_amt, mcp->m_item[item],
+ load_unload, atoi(p));
+ if (!load_comm_ok(sectp, sp->shp_own, item, move_amt))
return RET_OK;
- if (sectp->sct_oldown != player->cnum && item == I_CIVIL) {
- pr("%s civilians refuse to %s at %s!\n",
- move_amt < 0 ? "Your" : "Foreign",
- move_amt < 0 ? "disembark" : "board",
- xyas(sectp->sct_x, sectp->sct_y, player->cnum));
- return RET_FAIL;
- }
-
- if (!want_to_abandon(sectp, item, move_amt, 0))
+ if (!want_to_abandon(sectp, item, move_amt, NULL))
return RET_FAIL;
if (!still_ok_ship(sectp, sp))
return RET_SYN;
sectp->sct_item[item] = sect_amt - move_amt;
sp->shp_item[item] = ship_amt + move_amt;
+
if (move_amt >= 0) {
pr("%d %s loaded onto %s at %s\n",
move_amt, ich->i_name,
struct nstr_item ni;
struct plnstr pln;
int loaded = 0;
- s_char *p;
- s_char prompt[512];
- s_char buf[1024];
+ char *p;
+ char prompt[512];
+ char buf[1024];
+ struct lchrstr *lcp = lchr + lp->lnd_type;
- if (!lp->lnd_maxlight) {
+ if (!lcp->l_nxlight) {
if (noisy)
pr("%s cannot carry extra-light planes.\n", prland(lp));
return 0;
}
- count_land_planes(lp);
- if (load_unload == LOAD && lp->lnd_nxlight >= lp->lnd_maxlight) {
+ if (load_unload == LOAD && lnd_nxlight(lp) >= lcp->l_nxlight) {
if (noisy)
pr("%s doesn't have room for any more extra-light planes\n",
prland(lp));
}
sprintf(prompt, "Plane(s) to %s %s? ",
load_unload == LOAD ? "load onto" : "unload from", prland(lp));
- if (!snxtitem(&ni, EF_PLANE,
- p = getstarg(player->argp[3], prompt, buf)))
+ p = getstarg(player->argp[3], prompt, buf);
+ if (!p)
+ return RET_SYN;
+ if (!snxtitem(&ni, EF_PLANE, p, NULL))
return RET_SYN;
if (!still_ok_land(sectp, lp))
return RET_SYN;
- if (p && *p)
- noisy &= isdigit(*p);
-
- if (sectp->sct_own != player->cnum && load_unload == LOAD) {
- pr("Sector %s is not yours.\n",
- xyas(lp->lnd_x, lp->lnd_y, player->cnum));
- return 0;
- }
+ if (noisy && p && *p)
+ noisy = isdigit(*p);
while (nxtitem(&ni, &pln)) {
- if (pln.pln_own != player->cnum)
+ if (!player->owner)
continue;
if (!(plchr[(int)pln.pln_type].pl_flags & P_E)) {
prplane(&pln), pln.pln_land);
continue;
}
+ if (pln.pln_harden != 0) {
+ if (noisy)
+ pr("%s has been hardened and can't be loaded\n",
+ prplane(&pln));
+ continue;
+ }
+
/* Plane sanity done */
/* Find the right unit */
if (load_unload == UNLOAD) {
}
sprintf(buf, "loaded on %s at %s",
prland(lp), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
- gift(lp->lnd_own, player->cnum, &pln, EF_PLANE, buf);
- makelost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
- pln.pln_own = lp->lnd_own;
- makenotlost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
+ gift(lp->lnd_own, player->cnum, &pln, buf);
putplane(pln.pln_uid, &pln);
} else {
- if (!take_plane_off_land(&pln, lp)) {
- pr("Unable to take plane off unit!\n");
- logerror("load: plane %d could not be taken off unit %d\n",
- pln.pln_uid, lp->lnd_uid);
- continue;
- }
+ pln.pln_land = -1;
sprintf(buf, "unloaded at your sector at %s",
xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
- gift(sectp->sct_own, player->cnum, &pln, EF_PLANE, buf);
- makelost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
- pln.pln_own = sectp->sct_own;
- makenotlost(EF_PLANE, pln.pln_own, pln.pln_uid, pln.pln_x,
- pln.pln_y);
+ gift(sectp->sct_own, player->cnum, &pln, buf);
putplane(pln.pln_uid, &pln);
}
pr("%s %s %s at %s.\n",
{
i_type item = ich->i_uid;
struct lchrstr *lcp = &lchr[(int)lp->lnd_type];
- int land_amt, land_max, sect_amt, move_amt;
- int amount;
- s_char prompt[512];
- s_char *p;
- s_char buf[1024];
+ int land_amt, sect_amt, move_amt;
+ char prompt[512];
+ char *p;
+ char buf[1024];
sprintf(prompt, "Number of %s to %s %s at %s? ",
ich->i_name,
(load_unload == UNLOAD) ?
"unload from" : "load onto",
prland(lp), xyas(lp->lnd_x, lp->lnd_y, player->cnum));
- if (!(p = getstarg(player->argp[3], prompt, buf)) || !*p)
+ p = getstarg(player->argp[3], prompt, buf);
+ if (!p || !*p)
return RET_SYN;
if (!still_ok_land(sectp, lp))
return RET_SYN;
land_amt = lp->lnd_item[item];
- land_max = lcp->l_item[item];
sect_amt = sectp->sct_item[item];
- amount = atoi(p);
- if (amount < 0)
- move_amt = -amount - land_amt;
- else
- move_amt = load_unload == LOAD ? amount : -amount;
- if (move_amt > land_max - land_amt)
- move_amt = land_max - land_amt;
- if (move_amt < -land_amt)
- move_amt = -land_amt;
- if (move_amt > sect_amt)
- move_amt = sect_amt;
- if (move_amt < sect_amt - ITEM_MAX)
- move_amt = sect_amt - ITEM_MAX;
- if (!move_amt)
+ move_amt = move_amount(sect_amt, land_amt, lcp->l_item[item],
+ load_unload, atoi(p));
+ if (!load_comm_ok(sectp, lp->lnd_own, item, move_amt))
return RET_OK;
- if (sectp->sct_own != player->cnum && move_amt > 0) {
- pr("Sector %s is not yours.\n",
- xyas(lp->lnd_x, lp->lnd_y, player->cnum));
- return RET_FAIL;
- }
- if (sectp->sct_oldown != player->cnum && item == I_CIVIL) {
- pr("%s civilians refuse to %s at %s!\n",
- move_amt < 0 ? "Your" : "Foreign",
- move_amt < 0 ? "disembark" : "board",
- xyas(sectp->sct_x, sectp->sct_y, player->cnum));
- return RET_FAIL;
- }
sectp->sct_item[item] = sect_amt - move_amt;
lp->lnd_item[item] = land_amt + move_amt;
/* Did we put mils onto this unit? If so, reset the fortification */
if (item == I_MILIT && move_amt > 0)
lp->lnd_harden = 0;
+
if (move_amt >= 0) {
pr("%d %s loaded onto %s at %s\n",
move_amt, ich->i_name,
load_land_land(struct sctstr *sectp, struct lndstr *lp, int noisy,
int load_unload, int *nunitsp)
{
- struct nstr_item pni, ni;
+ struct nstr_item ni;
struct lndstr land;
- struct plnstr plane;
int loaded = 0;
- s_char *p;
- s_char prompt[512];
- s_char buf[1024];
-
- lnd_count_units(lp);
+ char *p;
+ char prompt[512];
+ char buf[1024];
- if (load_unload == LOAD && lp->lnd_nland >= lp->lnd_maxland) {
+ if (load_unload == LOAD
+ && lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) {
if (noisy) {
- if (lp->lnd_nland)
+ if (lchr[lp->lnd_type].l_nland)
pr("%s doesn't have room for any more land units!\n",
prland(lp));
else
}
sprintf(prompt, "Land unit(s) to %s %s? ",
load_unload == LOAD ? "load onto" : "unload from", prland(lp));
- if (!snxtitem(&ni, EF_LAND,
- p = getstarg(player->argp[3], prompt, buf)))
+ p = getstarg(player->argp[3], prompt, buf);
+ if (!p)
+ return RET_SYN;
+ if (!snxtitem(&ni, EF_LAND, p, NULL))
return RET_SYN;
if (!still_ok_land(sectp, lp))
return RET_SYN;
- if (p && *p)
- noisy &= isdigit(*p);
+ if (noisy && p && *p)
+ noisy = isdigit(*p);
while (nxtitem(&ni, &land)) {
-
- if (land.lnd_own != player->cnum)
+ if (!player->owner)
continue;
if (load_unload == LOAD) {
prland(&land), land.lnd_land);
continue;
}
- lnd_count_units(&land);
- if (land.lnd_nland > 0) {
+ if (lnd_first_on_land(&land) >= 0) {
if (noisy)
pr("%s cannot be loaded since it is carrying units\n",
prland(&land));
pr("%s can't be loaded onto itself!\n", prland(&land));
continue;
}
- if (lchr[(int)land.lnd_type].l_flags & L_HEAVY) {
+ if (lchr[(int)land.lnd_type].l_flags & (L_HEAVY | L_TRAIN)) {
if (noisy)
pr("%s is too heavy to load.\n", prland(&land));
continue;
/* Fit unit on ship */
if (load_unload == LOAD) {
- lnd_count_units(lp);
- if (lp->lnd_nland >= lp->lnd_maxland) {
+ if (lnd_nland(lp) >= lchr[lp->lnd_type].l_nland) {
if (noisy) {
- if (lp->lnd_nland)
+ if (lchr[lp->lnd_type].l_nland)
pr("%s doesn't have room for any more land units!\n",
prland(lp));
else
}
sprintf(buf, "loaded on your %s at %s",
prland(lp), xyas(lp->lnd_x, lp->lnd_y, lp->lnd_own));
- gift(lp->lnd_own, player->cnum, &land, EF_LAND, buf);
- makelost(EF_LAND, land.lnd_own, land.lnd_uid, land.lnd_x,
- land.lnd_y);
- land.lnd_own = lp->lnd_own;
- makenotlost(EF_LAND, land.lnd_own, land.lnd_uid, land.lnd_x,
- land.lnd_y);
+ gift(lp->lnd_own, player->cnum, &land, buf);
land.lnd_land = lp->lnd_uid;
land.lnd_harden = 0;
- land.lnd_mission = 0;
- resupply_all(&land);
- lp->lnd_nland++;
putland(land.lnd_uid, &land);
- if (!has_supply(&land))
+#if 0
+ /* FIXME same issue as in load_land_ship() */
+ if (!lnd_supply_all(&land))
pr("WARNING: %s is out of supply!\n", prland(&land));
- putland(lp->lnd_uid, lp);
- snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
- while (nxtitem(&pni, &plane)) {
- if (plane.pln_flags & PLN_LAUNCHED)
- continue;
- if (plane.pln_land != land.lnd_uid)
- continue;
- sprintf(buf, "loaded on %s", prland(lp));
- gift(lp->lnd_own, player->cnum, &plane, EF_PLANE, buf);
- makelost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_own = lp->lnd_own;
- makenotlost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_mission = 0;
- putplane(plane.pln_uid, &plane);
- }
+#else
+ if (!lnd_in_supply(&land))
+ pr("WARNING: %s is out of supply!\n", prland(&land));
+#endif
} else {
sprintf(buf, "unloaded in your %s at %s",
dchr[sectp->sct_type].d_name,
xyas(sectp->sct_x, sectp->sct_y, sectp->sct_own));
- gift(sectp->sct_own, player->cnum, &land, EF_LAND, buf);
- makelost(EF_LAND, land.lnd_own, land.lnd_uid, land.lnd_x,
- land.lnd_y);
- land.lnd_own = sectp->sct_own;
- makenotlost(EF_LAND, land.lnd_own, land.lnd_uid, land.lnd_x,
- land.lnd_y);
+ gift(sectp->sct_own, player->cnum, &land, buf);
land.lnd_land = -1;
- lp->lnd_nland--;
putland(land.lnd_uid, &land);
- putland(lp->lnd_uid, lp);
- snxtitem_xy(&pni, EF_PLANE, land.lnd_x, land.lnd_y);
- while (nxtitem(&pni, &plane)) {
- if (plane.pln_flags & PLN_LAUNCHED)
- continue;
- if (plane.pln_land != land.lnd_uid)
- continue;
- sprintf(buf, "unloaded at %s",
- xyas(plane.pln_x, plane.pln_y, sectp->sct_own));
- gift(sectp->sct_own, player->cnum, &plane, EF_PLANE, buf);
- makelost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_own = sectp->sct_own;
- makenotlost(EF_PLANE, plane.pln_own, plane.pln_uid,
- plane.pln_x, plane.pln_y);
- plane.pln_mission = 0;
- putplane(plane.pln_uid, &plane);
- }
}
pr("%s %s %s at %s.\n",
prland(&land),