/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
- * Ken Stevens, Steve McClure
+ * Copyright (C) 1986-2011, 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/>.
*
* ---
*
* Dave Pare, 1986
* Ken Stevens, 1995
* Steve McClure, 1998-2000
- * Markus Armbruster, 2004-2009
+ * Markus Armbruster, 2004-2010
*/
#include <config.h>
#include "file.h"
#include "item.h"
#include "land.h"
-#include "lost.h"
#include "map.h"
#include "misc.h"
#include "nat.h"
#include "nsc.h"
#include "nuke.h"
#include "optlist.h"
-#include "path.h"
#include "plane.h"
#include "player.h"
#include "prototypes.h"
#include "ship.h"
#include "xy.h"
-static int pln_equip(struct plist *, struct ichrstr *, char);
static int fit_plane_on_ship(struct plnstr *, struct shpstr *);
/*
return NULL;
/* over own or allied sector is fine */
- if (ap_sect->sct_own == player->cnum
- || getrel(getnatp(ap_sect->sct_own), player->cnum) == ALLIED)
+ if (relations_with(ap_sect->sct_own, player->cnum) == ALLIED)
return ap_sect;
/* over own or allied ship is fine */
while (nxtitem(&ni, &ship)) {
if (ship.shp_effic < SHIP_MINEFF || ship.shp_own == 0)
continue;
- if (ship.shp_own == player->cnum
- || getrel(getnatp(ship.shp_own), player->cnum) == ALLIED)
+ if (relations_with(ship.shp_own, player->cnum) == ALLIED)
return ap_sect;
}
if (cno < 0
|| !getship(cno, &ship)
|| (!player->owner
- && (getrel(getnatp(ship.shp_own), player->cnum)
+ && (relations_with(ship.shp_own, player->cnum)
!= ALLIED))) {
pr("Not yours\n");
continue;
}
/* try to land at sector */
- if (target->sct_own != player->cnum
- && getrel(getnatp(target->sct_own), player->cnum) != ALLIED) {
+ if (relations_with(target->sct_own, player->cnum) != ALLIED) {
pr("Nowhere to land at sector %s!\n",
xyas(target->sct_x, target->sct_y, player->cnum));
return -1;
amt = 0;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
plp = (struct plist *)qp;
- amt += plp->misc;
+ amt += plp->load;
}
if (cno < 0) {
getsect(tx, ty, §);
pr("Your %s vanish without a trace.\n", ip->i_name);
return;
}
- if (sect.sct_own != player->cnum
- && getrel(getnatp(sect.sct_own), player->cnum) != ALLIED) {
+ if (relations_with(sect.sct_own, player->cnum) != ALLIED) {
pr("You don't own %s! Cargo jettisoned...\n",
xyas(tx, ty, player->cnum));
return;
}
there += amt;
if (there > max) {
- pr("%d excess %s discarded\n", max - there, ip->i_name);
- amt = max - there;
+ pr("%d excess %s discarded\n", there - max, ip->i_name);
+ amt -= there - max;
there = max;
}
pr("%d %s landed safely", amt, ip->i_name);
amt = 0;
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
plp = (struct plist *)qp;
- amt += plp->misc;
+ amt += plp->load;
}
if (amt > 0) {
/*
* Has PP's type capabilities satisfying WANTFLAGS and NOWANTFLAGS?
* A plane type is capable unless
+ * - it lacks all of the P_B, P_T in WANTFLAGS, or
* - it lacks all of the P_F, P_ESC in WANTFLAGS, or
* - it lacks all of the P_E, P_L, P_K in WANTFLAGS, or
* - it lacks any of the other capabilities in WANTFLAGS, or
{
int flags = plchr[(int)pp->pln_type].pl_flags;
+ if (wantflags & (P_B | P_T)) {
+ if ((flags & wantflags & (P_B | P_T)) == 0)
+ return 0;
+ wantflags &= ~(P_B | P_T);
+ }
+
if (wantflags & (P_F | P_ESC)) {
if ((flags & wantflags & (P_F | P_ESC)) == 0)
return 0;
CANT_REACH();
return 0;
}
- if (ship.shp_own != pp->pln_own
- && getrel(getnatp(ship.shp_own), pp->pln_own) != ALLIED) {
+ if (relations_with(ship.shp_own, pp->pln_own) != ALLIED) {
if (noisy)
pr("(note) An ally does not own the ship %s is on\n",
prplane(pp));
CANT_REACH();
return 0;
}
- if (land.lnd_own != pp->pln_own
- && getrel(getnatp(land.lnd_own), pp->pln_own) != ALLIED) {
+ if (relations_with(land.lnd_own, pp->pln_own) != ALLIED) {
if (noisy)
pr("(note) An ally does not own the unit %s is on\n",
prplane(pp));
return 0;
}
- if (sect.sct_own != pp->pln_own
- && getrel(getnatp(sect.sct_own), pp->pln_own) != ALLIED) {
+ if (relations_with(sect.sct_own, pp->pln_own) != ALLIED) {
if (noisy)
pr("(note) An ally does not own the sector %s is in\n",
prplane(pp));
if (sect.sct_effic < 40) {
if (noisy)
pr("%s is not 40%% efficient, %s can't take off from there.\n",
- xyas(sect.sct_x, sect.sct_y, pp->pln_own),
+ xyas(sect.sct_x, sect.sct_y, player->cnum),
prplane(pp));
return 0;
}
if (!oneway && sect.sct_effic < 60) {
if (noisy)
pr("%s is not 60%% efficient, %s can't land there.\n",
- xyas(sect.sct_x, sect.sct_y, pp->pln_own),
+ xyas(sect.sct_x, sect.sct_y, player->cnum),
prplane(pp));
return 0;
}
emp_initque(list);
while (nxtitem(ni, &plane)) {
- if (!player->owner)
+ /*
+ * It would be nice to let deities fly foreign planes, but
+ * much of the code assumes that only the plane's owner can
+ * fly it.
+ */
+ if (!plane.pln_own || plane.pln_own != player->cnum)
continue;
if (plane.pln_mobil <= 0)
continue;
plane.pln_mission = 0;
putplane(plane.pln_uid, &plane);
plp = malloc(sizeof(struct plist));
- plp->misc = 0;
- plp->bombs = 0;
+ plp->load = 0;
plp->pcp = pcp;
plp->plane = plane;
emp_insque(&plp->queue, list);
}
}
-static int
+int
pln_equip(struct plist *plp, struct ichrstr *ip, char mission)
{
struct plchrstr *pcp;
item[I_PETROL] -= pcp->pl_fuel;
load = pln_load(pp);
itype = I_NONE;
- needed = 0;
switch (mission) {
case 's': /* strategic bomb */
case 'p': /* pinpoint bomb */
- if (nuk_on_plane(pp) < 0) {
- itype = I_SHELL;
- needed = load;
- }
+ itype = I_SHELL;
break;
case 't': /* transport */
- case 'd': /* drop */
if (!(pcp->pl_flags & P_C) || !ip)
break;
itype = ip->i_uid;
- needed = (load * 2) / ip->i_lbs;
+ load *= 2;
break;
case 'm': /* mine */
if ((pcp->pl_flags & P_MINE) == 0)
break;
itype = I_SHELL;
- needed = (load * 2) / ichr[I_SHELL].i_lbs;
+ load *= 2;
+ break;
+ case 'd': /* drop */
+ if (!(pcp->pl_flags & P_C) || CANT_HAPPEN(!ip))
+ break;
+ itype = ip->i_uid;
+ if (pcp->pl_flags & P_V)
+ load *= 2;
break;
case 'a': /* paradrop */
- if ((pcp->pl_flags & (P_V | P_C)) == 0)
+ if (!(pcp->pl_flags & P_P))
break;
itype = I_MILIT;
- needed = load / ichr[I_MILIT].i_lbs;
+ if (pcp->pl_flags & P_V)
+ load *= 2;
break;
case 'r': /* reconnaissance */
case 'e': /* escort */
+ load = 0;
+ break;
+ case 'i': /* missile interception */
+ if (CANT_HAPPEN(!(pcp->pl_flags & P_M)
+ || !(pcp->pl_flags & (P_N | P_O))))
+ break;
+ if (load)
+ itype = I_SHELL;
break;
default:
CANT_REACH();
+ load = 0;
}
- if (itype != I_NONE && needed <= 0) {
- pr("%s can't contribute to mission\n", prplane(pp));
- return -1;
- }
- if (itype == I_CIVIL && pp->pln_own != own) {
- pr("You don't control those civilians!\n");
- return -1;
- }
+
if (itype != I_NONE) {
+ needed = load / ichr[itype].i_lbs;
+ if (needed <= 0) {
+ pr("%s can't contribute to mission\n", prplane(pp));
+ return -1;
+ }
+ if (nuk_on_plane(pp) >= 0) {
+ if (mission == 's' || mission == 't')
+ needed = 0;
+ else {
+ pr("%s can't fly this mission"
+ " while it is carrying a nuclear weapon",
+ prplane(pp));
+ return -1;
+ }
+ }
+ if (itype == I_CIVIL && pp->pln_own != own) {
+ pr("You don't control those civilians!\n");
+ return -1;
+ }
#if 0
/* Supply is broken somewhere, so don't use it for now */
if (itype == I_SHELL && item[itype] < needed)
plp->plane.pln_y,
I_SHELL, needed);
#endif
- abandon_needed = !!would_abandon(§, itype, needed, NULL);
+ if (pp->pln_ship >= 0 || pp->pln_land >= 0)
+ abandon_needed = 0;
+ else
+ abandon_needed = !!would_abandon(§, itype, needed, NULL);
if (item[itype] < needed + abandon_needed) {
pr("Not enough %s for %s\n", ichr[itype].i_name, prplane(pp));
return -1;
}
item[itype] -= needed;
+ plp->load = needed;
}
- if (itype == I_SHELL && (mission == 's' || mission == 'p'))
- plp->bombs = needed;
- else
- plp->misc = needed;
+
if (pp->pln_ship >= 0) {
if (pp->pln_own != ship.shp_own) {
wu(0, ship.shp_own,
{
struct plchrstr *pcp = &plchr[pp->pln_type];
struct mchrstr *mcp = &mchr[sp->shp_type];
+ int nfw;
if (pcp->pl_flags & P_K)
nch++;
else if (pcp->pl_flags & P_M)
nmsl++;
n++;
+ nfw = n - nch - nxl - nmsl;
- n -= MIN(nch, mcp->m_nchoppers);
- n -= MIN(nxl, mcp->m_nxlight);
+ if (nch > mcp->m_nchoppers) /* overflow into fixed-wing slots */
+ nfw += nch - mcp->m_nchoppers;
+ if (nxl > mcp->m_nxlight) /* overflow into missile slots */
+ nmsl += nxl - mcp->m_nxlight;
if (nmsl && !(mcp->m_flags & (M_MSL | M_FLY)))
return 0; /* missile slots wanted */
- if (nmsl < n && !(mcp->m_flags & M_FLY))
+ if (nfw && !(mcp->m_flags & M_FLY))
return 0; /* fixed-wing slots wanted */
- return n <= mcp->m_nplanes;
+ return nfw + nmsl <= mcp->m_nplanes;
}
/*
if (chance((100.0 - pln_acc(pp)) / 100.0)) {
pr("Sweep! in %s\n",
- xyas(sect.sct_x, sect.sct_y, pp->pln_own));
+ xyas(sect.sct_x, sect.sct_y, player->cnum));
mines_there--;
found = 1;
}
return hitchance;
}
-/* return 0 if there was a nuclear detonation */
-
int
-pln_damage(struct plnstr *pp, coord x, coord y, char type, int *nukedamp,
- int noisy)
+pln_damage(struct plnstr *pp, char type, int noisy)
{
- struct nukstr nuke;
struct plchrstr *pcp = plchr + pp->pln_type;
- int load, i;
- int hitroll;
+ int load, i, hitroll, aim, len;
int dam = 0;
- int aim;
int effective = 1;
int pinbomber = 0;
+ char buf[80];
- if (getnuke(nuk_on_plane(pp), &nuke)) {
- mpr(pp->pln_own, "Releasing RV's for %s detonation...\n",
- pp->pln_flags & PLN_AIRBURST ? "airburst" : "groundburst");
- *nukedamp = detonate(&nuke, x, y,
- pp->pln_flags & PLN_AIRBURST);
+ if (CANT_HAPPEN(nuk_on_plane(pp) >= 0))
return 0;
- }
- *nukedamp = 0;
load = pln_load(pp);
if (!load) /* e.g. ab, blowing up on launch pad */
aim = 100 - aim;
}
+ len = 0;
while (i--) {
dam += roll(6);
hitroll = roll(100);
if (hitroll >= 90) {
dam += 8;
if (noisy)
- mpr(pp->pln_own, "BLAM");
+ len += sprintf(buf + len, "BLAM");
} else if (hitroll < aim) {
dam += 5;
if (noisy)
- mpr(pp->pln_own, "Blam");
+ len += sprintf(buf + len, "Blam");
} else {
dam += 1;
if (noisy)
- mpr(pp->pln_own, "blam");
+ len += sprintf(buf + len, "blam");
+ }
+ if (noisy) {
+ if (len > 75) {
+ mpr(pp->pln_own, "%s\n", buf);
+ len = 0;
+ }
+ if (i)
+ len += sprintf(buf + len, "-");
}
- if (i && noisy)
- mpr(pp->pln_own, "-");
}
- if (noisy)
- mpr(pp->pln_own, "\n");
+ if (noisy && len)
+ mpr(pp->pln_own, "%s\n", buf);
if (effective)
dam *= 2;
return dam;