/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2008, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
#include <config.h>
+#include <stdlib.h>
+#include "empobj.h"
+#include "file.h"
+#include "item.h"
#include "misc.h"
-#include "player.h"
-#include "xy.h"
-#include "sect.h"
-#include "ship.h"
-#include "land.h"
-#include "plane.h"
-#include "nat.h"
+#include "mission.h"
#include "nsc.h"
-#include "file.h"
+#include "optlist.h"
#include "path.h"
-#include "mission.h"
-#include "genitem.h"
-#include "news.h"
-#include "item.h"
-#include <fcntl.h>
-#include "damage.h"
-#include "queue.h"
+#include "player.h"
#include "prototypes.h"
-#include "optlist.h"
+#include "queue.h"
+#include "xy.h"
struct genlist {
struct emp_qelem queue; /* list of units */
- int type; /* unit type: EF_SHIP, EF_PLANE, EF_LAND */
void *cp; /* pointer to desc of thing */
- void *thing; /* thing's struct */
+ struct empobj *thing; /* thing's struct */
};
struct airport {
natid own;
};
-union item_u {
- struct shpstr ship;
- struct plnstr plane;
- struct lndstr land;
-};
-
static void add_airport(struct emp_qelem *, coord, coord);
static int air_damage(struct emp_qelem *, coord, coord, int, natid,
- s_char *, int);
+ char *, int);
static void build_mission_list(struct genlist *, coord, coord, int, natid);
static void build_mission_list_type(struct genlist *, coord, coord, int,
int, natid);
static int dosupport(struct genlist *, coord, coord, natid, natid);
static int find_airport(struct emp_qelem *, coord, coord);
static int mission_pln_arm(struct emp_qelem *, coord, coord, int,
- int, struct ichrstr *, int, int, int *);
+ int, struct ichrstr *, int, int);
static void mission_pln_sel(struct emp_qelem *, int, int, int);
static int perform_mission(coord, coord, natid, struct emp_qelem *, int,
- s_char *, int);
+ char *, int);
/*
* Interdict commodities & transported planes
*/
int
-ground_interdict(coord x, coord y, natid victim, s_char *s)
+ground_interdict(coord x, coord y, natid victim, char *s)
{
int cn;
int dam = 0, newdam, rel;
cname(cn), newdam);
}
if (dam) {
- collateral_damage(x, y, dam, 0);
+ collateral_damage(x, y, dam);
}
return dam;
}
int
-collateral_damage(coord x, coord y, int dam, struct emp_qelem *list)
+collateral_damage(coord x, coord y, int dam)
{
int coll;
struct sctstr sect;
return 0;
mpr(sect.sct_own, "%s takes %d%% collateral damage\n",
xyas(x, y, sect.sct_own), coll);
- sectdamage(§, coll, list);
+ sectdamage(§, coll);
putsect(§);
return coll;
}
for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
glp = (struct genlist *)qp;
- if (glp->type != EF_SHIP)
+ if (glp->thing->ef_type != EF_SHIP)
return 0;
mcp = glp->cp;
if (!(mcp->m_flags & M_SUB))
/*
* Interdict ships & land units
- *
*/
int
-unit_interdict(coord x, coord y, natid victim, s_char *s, int hardtarget,
+unit_interdict(coord x, coord y, natid victim, char *s, int hardtarget,
int mission)
{
int cn;
}
}
if (dam) {
- collateral_damage(x, y, dam, 0);
+ collateral_damage(x, y, dam);
}
return dam;
}
{
struct nstr_item ni;
struct genlist *glp;
- struct genitem *gp;
- union item_u item;
+ struct empobj *gp;
+ union empobj_storage item;
int dist;
int radius;
int relat;
snxtitem_all(&ni, type);
while (nxtitem(&ni, &item)) {
- gp = (struct genitem *)&item;
+ gp = (struct empobj *)&item;
if (gp->own == 0)
continue;
radius = gp->radius;
if (mission != MI_RESERVE) /* XXX */
- oprange(gp, type, &radius);
+ oprange(gp, &radius);
if (dist > radius)
continue;
/* Now check from where the object actually is */
dist = mapdist(x, y, gp->x, gp->y);
radius = 999;
- oprange(gp, type, &radius);
+ oprange(gp, &radius);
if (dist > radius)
continue;
/* Ok, the object can get to where the x,y is */
if (getrel(getnatp(gp->own), sect.sct_own) > AT_WAR) {
/*
- * If the player->owner of the unit isn't at war
+ * If the owner of the unit isn't at war
* with the victim, and doesn't own the
* sect being acted upon, and isn't the
- * old player->owner of that sect, bounce them.
+ * old owner of that sect, bounce them.
*/
if (sect.sct_type != SCT_WATER &&
sect.sct_own != gp->own &&
glp = malloc(sizeof(struct genlist));
memset(glp, 0, sizeof(struct genlist));
- glp->type = type;
- switch (type) {
- case EF_LAND:
- glp->cp = &lchr[(int)gp->type];
- break;
- case EF_SHIP:
- glp->cp = &mchr[(int)gp->type];
- break;
- case EF_PLANE:
- glp->cp = &plchr[(int)gp->type];
- break;
- }
+ glp->cp = get_empobj_chr(gp);
glp->thing = malloc(sizeof(item));
memcpy(glp->thing, &item, sizeof(item));
emp_insque(&glp->queue, &mi[gp->own].queue);
continue;
dist = mapdist(x, y, plane.pln_x, plane.pln_y);
-
- if (dist > ((int)((float)plane.pln_range / 2.0)))
+ if (dist > plane.pln_range / 2)
continue;
plp = malloc(sizeof(struct plist));
static int
perform_mission(coord x, coord y, natid victim, struct emp_qelem *list,
- int mission, s_char *s, int hardtarget)
+ int mission, char *s, int hardtarget)
{
struct emp_qelem *qp, missiles, bombers, escorts, airp, b, e;
struct emp_qelem *newqp;
struct genlist *glp;
struct plist *plp;
- struct genitem *gp;
+ struct empobj *gp;
struct lndstr *lp;
struct shpstr *sp;
struct sctstr sect;
struct mchrstr *mcp;
struct plchrstr *pcp;
- int dam = 0, dam2, mission_flags, tech;
+ int dam = 0, dam2, mission_flags;
natid plane_owner = 0;
- int gun, shell, md, air_dam = 0;
- double range2, prb, range, mobcost, hitchance;
+ int md, range, air_dam = 0;
+ double prb, hitchance, vrange;
+ int targeting_ships = *s == 's'; /* "subs" or "ships" FIXME gross! */
getsect(x, y, §);
md = mapdist(x, y, gp->x, gp->y);
- if (glp->type == EF_LAND) {
- lp = glp->thing;
-
- if (lp->lnd_effic < LAND_MINFIREEFF)
- continue;
+ if (glp->thing->ef_type == EF_LAND) {
+ lp = (struct lndstr *)glp->thing;
if (mission == MI_SINTERDICT)
continue;
(md > land_max_interdiction_range))
continue;
- if (md > (lp->lnd_frg / 2))
- continue;
-
- if ((lp->lnd_ship != -1) || (lp->lnd_land != -1))
+ /* Too ponderous for interdiction fire */
+ if (lchr[(int)lp->lnd_type].l_flags & L_HEAVY)
continue;
- if (lnd_getmil(lp) < 1)
+ range = roundrange(lnd_fire_range(lp));
+ if (md > range)
continue;
- range = techfact((int)lp->lnd_tech, (double)lp->lnd_frg / 2.0);
- range2 = (double)roundrange(range);
-
- if (md > range2)
+ dam2 = lnd_fire(lp);
+ putland(lp->lnd_uid, lp);
+ if (dam2 < 0)
continue;
- shell = lp->lnd_item[I_SHELL];
- gun = lp->lnd_item[I_GUN];
- if (shell == 0 || gun == 0)
- continue;
-
- if (has_supply(lp)) {
- use_supply(lp);
- putland(lp->lnd_uid, lp);
- dam2 = ldround(landunitgun(lp->lnd_effic, lp->lnd_dam, gun,
- lp->lnd_ammo, shell), 1);
- if (sect.sct_type == SCT_WATER) {
- double dam3 = (double)dam2;
- if (chance(((double)lp->lnd_acc) / 100.0))
- dam2 = ldround((dam3 / 2.0), 1);
- }
- dam += dam2;
- if (sect.sct_type == SCT_WATER)
- nreport(lp->lnd_own, N_SHP_SHELL, victim, 1);
- else
- nreport(lp->lnd_own, N_SCT_SHELL, victim, 1);
- wu(0, lp->lnd_own,
- "%s fires at %s %s at %s\n",
- prland(lp), cname(victim), s, xyas(x, y, lp->lnd_own));
-
- mpr(victim, "%s %s fires at you at %s\n",
- cname(lp->lnd_own), prland(lp), xyas(x, y, victim));
+ if (targeting_ships) {
+ if (chance(lnd_acc(lp) / 100.0))
+ dam2 = ldround(dam2 / 2.0, 1);
}
- } else if (glp->type == EF_SHIP) {
- sp = glp->thing;
+ dam += dam2;
+ if (targeting_ships)
+ nreport(lp->lnd_own, N_SHP_SHELL, victim, 1);
+ else
+ nreport(lp->lnd_own, N_SCT_SHELL, victim, 1);
+ wu(0, lp->lnd_own,
+ "%s fires at %s %s at %s\n",
+ prland(lp), cname(victim), s, xyas(x, y, lp->lnd_own));
+
+ mpr(victim, "%s %s fires at you at %s\n",
+ cname(lp->lnd_own), prland(lp), xyas(x, y, victim));
+ } else if (glp->thing->ef_type == EF_SHIP) {
+ sp = (struct shpstr *)glp->thing;
mcp = glp->cp;
- if (sp->shp_effic < 60)
- continue;
- if (sp->shp_frnge == 0)
- continue;
if (((mission == MI_INTERDICT) ||
(mission == MI_SINTERDICT)) &&
(md > ship_max_interdiction_range))
continue;
- if (sp->shp_item[I_MILIT] < 1)
- continue;
/*
if ((mcp->m_flags & M_SUB) &&
(sect.sct_type != SCT_WATER))
continue;
if (!(mcp->m_flags & M_DCH) && !(mcp->m_flags & M_SUBT))
continue;
- range2 = techfact(sp->shp_tech, (double)mcp->m_vrnge);
- range2 *= (double)sp->shp_effic / 200.0;
- if (md > range2)
+ vrange = techfact(sp->shp_tech, mcp->m_vrnge);
+ vrange *= sp->shp_effic / 200.0;
+ if (md > vrange)
continue;
/* can't look all the time */
if (chance(0.5))
continue;
}
if (mcp->m_flags & M_SUB) {
-/* If we aren't shooting at "subs" or "ships" don't fire at all from
- a sub. */
- if (*s != 's')
- continue;
- if (sp->shp_mobil < 0)
- continue;
- gun = sp->shp_item[I_GUN];
- if (gun < 1)
- continue;
- shell = sp->shp_item[I_SHELL];
- if (shell < SHP_TORP_SHELLS)
- shell += supply_commod(sp->shp_own,
- sp->shp_x, sp->shp_y, I_SHELL,
- SHP_TORP_SHELLS - shell);
- if (shell < SHP_TORP_SHELLS)
- continue;
-
- range = sp->shp_effic * techfact(sp->shp_tech,
- ((double)sp->shp_frnge)) /
- 100.0;
-
- range2 = (double)roundrange(range);
+ if (!targeting_ships)
+ continue; /* subs interdict only ships */
+ range = roundrange(torprange(sp));
if (md > range)
continue;
-
if (!line_of_sight(NULL, x, y, gp->x, gp->y))
continue;
- sp->shp_item[I_SHELL] = shell - SHP_TORP_SHELLS;
- mobcost = sp->shp_effic * 0.01 * sp->shp_speed;
- mobcost = (480.0 / (mobcost +
- techfact(sp->shp_tech, mobcost)));
- sp->shp_mobil -= mobcost;
+ dam2 = shp_torp(sp, 1);
putship(sp->shp_uid, sp);
- hitchance = DTORP_HITCHANCE(md, sp->shp_visib);
+ if (dam2 < 0)
+ continue;
+ hitchance = shp_torp_hitchance(sp, md);
wu(0, sp->shp_own,
"%s locking on %s %s in %s\n",
prship(sp), cname(victim), s, xyas(x, y, sp->shp_own));
wu(0, sp->shp_own,
- "\tEffective torpedo range is %.1f\n", range);
+ "\tEffective torpedo range is %d.0\n", range);
wu(0, sp->shp_own,
"\tWhooosh... Hitchance = %d%%\n",
(int)(hitchance * 100));
- if (hitchance < 1.0 && !chance(hitchance)) {
+ if (!chance(hitchance)) {
wu(0, sp->shp_own, "\tMissed\n");
mpr(victim,
"Incoming torpedo sighted @ %s missed (whew)!\n",
continue;
}
wu(0, sp->shp_own, "\tBOOM!...\n");
- dam2 = TORP_DAMAGE();
-
dam += dam2;
nreport(victim, N_TORP_SHIP, 0, 1);
wu(0, sp->shp_own,
"Incoming torpedo sighted @ %s hits and does %d damage!\n",
xyas(x, y, victim), dam2);
} else {
- range = techfact(sp->shp_tech, (double)mcp->m_frnge / 2.0);
- range2 = (double)roundrange(range);
- if (md > range2)
+ range = roundrange(shp_fire_range(sp));
+ if (md > range)
continue;
- gun = sp->shp_item[I_GUN];
- gun = MIN(gun, sp->shp_glim);
- shell = sp->shp_item[I_SHELL];
- if (shell < gun)
- shell += supply_commod(sp->shp_own,
- sp->shp_x, sp->shp_y, I_SHELL,
- gun - shell);
- gun = MIN(gun, shell);
- gun = MIN(gun, sp->shp_item[I_MILIT] / 2.0);
- if (gun == 0)
+ if (mission == MI_SINTERDICT)
+ dam2 = shp_dchrg(sp);
+ else
+ dam2 = shp_fire(sp);
+ putship(sp->shp_uid, sp);
+ if (dam2 < 0)
continue;
- gun = MAX(gun, 1);
- dam2 = seagun(sp->shp_effic, gun);
- if (range2 == 0.0)
+ if (range == 0.0)
prb = 1.0;
else
- prb = ((double)md) / range2;
+ prb = (double)md / range;
prb *= prb;
if (chance(prb))
- dam2 = (int)((float)dam2 / 2.0);
+ dam2 /= 2;
dam += dam2;
- if (sect.sct_type == SCT_WATER)
+ if (targeting_ships)
nreport(sp->shp_own, N_SHP_SHELL, victim, 1);
else
nreport(sp->shp_own, N_SCT_SHELL, victim, 1);
mpr(victim, "%s %s fires at you at %s\n",
cname(sp->shp_own), prship(sp), xyas(x, y, victim));
-
- sp->shp_item[I_SHELL] = shell - gun;
- putship(sp->shp_uid, sp);
}
- } else if (glp->type == EF_PLANE) {
+ } else if (glp->thing->ef_type == EF_PLANE) {
pcp = glp->cp;
if (pcp->pl_flags & P_M)
/* units have their own missile interdiction */
else
emp_insque(&plp->queue, &bombers);
plane_owner = plp->plane.pln_own;
+ } else {
+ CANT_REACH();
+ break;
}
}
if (!QEMPTY(&missiles)) {
/* Split off the escorts at this base into e */
divide(&escorts, &e, air->x, air->y);
- tech = 0;
mission_flags = 0;
mission_flags |= P_X; /* stealth (shhh) */
mission_flags |= P_H; /* gets turned off if not all choppers */
mission_flags = mission_pln_arm(&b, air->x, air->y, 2 * md, 'p', 0,
- 0, mission_flags, &tech);
+ 0, mission_flags);
if (QEMPTY(&b))
continue;
mission_flags = mission_pln_arm(&e, air->x, air->y, 2 * md, 'p', 0,
- P_F | P_ESC, mission_flags, &tech);
+ P_F | P_ESC, mission_flags);
pp = BestAirPath(buf, air->x, air->y, x, y);
if (CANT_HAPPEN(!pp))
xyas(air->x, air->y, air->own));
}
- ac_encounter(&b, &e, air->x, air->y, pp, mission_flags, 0, 0, 0);
+ ac_encounter(&b, &e, air->x, air->y, pp, mission_flags, 0);
if (!QEMPTY(&b))
air_dam +=
if (air_dam > 0) {
dam += air_dam;
- if (sect.sct_type == SCT_WATER)
+ if (targeting_ships)
nreport(plane_owner, N_SHP_BOMB, victim, 1);
else
nreport(plane_owner, N_SCT_BOMB, victim, 1);
return 0;
}
-s_char *
-nameofitem(struct genitem *gp, int type)
-{
- switch (type) {
- case EF_SHIP:
- return prship((struct shpstr *)gp);
- case EF_PLANE:
- return prplane((struct plnstr *)gp);
- case EF_LAND:
- return prland((struct lndstr *)gp);
- }
- return NULL;
-}
-
-s_char *
-mission_name(short int mission)
+char *
+mission_name(short mission)
{
switch (mission) {
case MI_INTERDICT:
show_mission(int type, struct nstr_item *np)
{
int first = 1, radius;
- union item_u item;
- struct genitem *gp;
+ union empobj_storage item;
+ struct empobj *gp;
while (nxtitem(np, &item)) {
- gp = (struct genitem *)&item;
+ gp = (struct empobj *)&item;
if (!player->owner || gp->own == 0)
continue;
pr("Thing x,y op-sect rad mission\n");
first = 0;
}
- pr("%-25s", nameofitem(gp, type));
+ pr("%-25s", obj_nameof(gp));
prxy(" %3d,%-3d", gp->x, gp->y, player->cnum);
if (gp->mission == MI_INTERDICT || gp->mission == MI_SUPPORT ||
gp->mission == MI_OSUPPORT ||
gp->mission == MI_DSUPPORT || gp->mission == MI_AIR_DEFENSE) {
radius = 999;
- oprange(gp, type, &radius);
+ oprange(gp, &radius);
prxy(" %3d,%-3d", gp->opx, gp->opy, player->cnum);
if (radius < gp->radius)
pr(" %4d", radius);
pr(" %4d", plus);
} else if (gp->mission == MI_ESCORT) {
pr(" ");
- pr(" %4d", (int)(item.plane.pln_range / 2.0));
+ pr(" %4d", item.plane.pln_range / 2);
} else
pr(" ");
if (gp->mission)
}
int
-oprange(struct genitem *gp, int type, int *radius)
+oprange(struct empobj *gp, int *radius)
{
int range;
- struct shpstr ship;
- struct lndstr land;
- struct plnstr plane;
- switch (type) {
+ switch (gp->ef_type) {
case EF_SHIP:
- getship(gp->uid, &ship);
- range = ldround(techfact(gp->tech,
- (double)ship.shp_frnge / 2.0), 1);
+ range = ldround(shp_fire_range((struct shpstr *)gp), 1);
break;
case EF_LAND:
- getland(gp->uid, &land);
- range = ldround(techfact((int)land.lnd_tech,
- (double)land.lnd_frg / 2.0), 1);
+ range = ldround(lnd_fire_range((struct lndstr *)gp), 1);
break;
case EF_PLANE:
- getplane(gp->uid, &plane);
/* missiles go one way, so we can use all the range */
- if (plchr[(int)plane.pln_type].pl_flags & P_M)
- range = plane.pln_range;
+ if (plchr[(int)gp->type].pl_flags & P_M)
+ range = ((struct plnstr *)gp)->pln_range;
else
- range = ldround((double)plane.pln_range / 2.0, 1);;
+ range = ((struct plnstr *)gp)->pln_range / 2;
break;
default:
- CANT_HAPPEN("bad TYPE");
+ CANT_REACH();
range = -1;
}
{
struct emp_qelem *qp, *next;
struct plnstr *pp;
- struct shpstr ship;
- struct lndstr land;
- struct sctstr sect;
struct plchrstr *pcp;
struct plist *plp;
- int y, bad, bad1;
- unsigned int x;
for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
}
}
- bad = 0;
- bad1 = 0;
- if (wantflags) {
- for (x = 0; x < sizeof(wantflags) * 8; x++) {
- y = (1 << x);
- if ((wantflags & y) == y)
- if ((pcp->pl_flags & y) != y) {
- switch (y) {
- case P_F:
- case P_ESC:
- bad1 = 2;
- break;
- case P_E:
- case P_L:
- case P_K:
- bad1 = 1;
- break;
- default:
- bad = 1;
- }
- }
- }
- if (bad) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- if (bad1 == 2) {
- if ((pcp->pl_flags & P_ESC) || (pcp->pl_flags & P_F))
- bad1 = 0;
- }
- if (bad1 == 1) {
- if ((pcp->pl_flags & P_E) ||
- (pcp->pl_flags & P_K) || (pcp->pl_flags & P_L))
- bad1 = 0;
- }
- if (bad1) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- }
- bad = 0;
- bad1 = 0;
- if (nowantflags) {
- for (x = 0; x < sizeof(nowantflags) * 8; x++) {
- y = (1 << x);
- if ((nowantflags & y) == y)
- if ((pcp->pl_flags & y) == y)
- bad = 1;
- }
- if (bad) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- }
- if (pp->pln_ship >= 0) {
- if (!getship(pp->pln_ship, &ship)) {
- shipsunk:
- pp->pln_effic = 0;
- putplane(pp->pln_uid, pp);
- emp_remque(qp);
- free(qp);
- continue;
- }
- if (!can_be_on_ship(pp->pln_uid, ship.shp_uid)) {
- goto shipsunk;
- }
- if (ship.shp_effic < SHIP_MINEFF) {
- goto shipsunk;
- }
- /* Can't fly off of inefficient or non-owned, non-allied ships */
- if ((ship.shp_effic < SHP_AIROPS_EFF) ||
- ((ship.shp_own != pp->pln_own) &&
- (getrel(getnatp(ship.shp_own), pp->pln_own) != ALLIED))) {
- emp_remque(qp);
- free(qp);
- continue;
- }
+ if (!pln_capable(pp, wantflags, nowantflags)) {
+ emp_remque(qp);
+ free(qp);
+ continue;
}
- if (pp->pln_land >= 0) {
- if (!getland(pp->pln_land, &land)) {
- landdead:
- pp->pln_effic = 0;
- putplane(pp->pln_uid, pp);
- emp_remque(qp);
- free(qp);
- continue;
- }
- if (!(pcp->pl_flags & P_E))
- goto landdead;
- if (land.lnd_effic < LAND_MINEFF)
- goto landdead;
-
- /* Can't fly off of inefficient or non-owned, non-allied units */
- if ((land.lnd_effic < LND_AIROPS_EFF) ||
- ((land.lnd_own != pp->pln_own) &&
- (getrel(getnatp(land.lnd_own), pp->pln_own) != ALLIED))) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- /* Can't fly off units in ships or other units */
- if ((land.lnd_ship >= 0) || (land.lnd_land >= 0)) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- }
- /* Now, check the sector status if not on a plane or unit */
- if ((pp->pln_ship < 0) && (pp->pln_land < 0)) {
- /* If we can't get the sector, we can't check it, and can't fly */
- if (!getsect(pp->pln_x, pp->pln_y, §)) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- /* First, check allied status */
- /* Can't fly from non-owned sectors or non-allied sectors */
- if ((sect.sct_own != pp->pln_own) &&
- (getrel(getnatp(sect.sct_own), pp->pln_own) != ALLIED)) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- /* non-vtol plane */
- if ((pcp->pl_flags & P_V) == 0) {
- if ((sect.sct_type != SCT_AIRPT) || (sect.sct_effic < 40)) {
- emp_remque(qp);
- free(qp);
- continue;
- }
- }
+ if (!pln_airbase_ok(pp, 0, 0)) {
+ emp_remque(qp);
+ free(qp);
+ continue;
}
+
if (pcp->pl_flags & P_A) {
if (roll(100) > pln_identchance(pp, hardtarget, EF_SHIP)) {
emp_remque(qp);
/*
* Arm only the planes at x,y
- *
*/
static int
mission_pln_arm(struct emp_qelem *list, coord x, coord y, int dist,
int mission, struct ichrstr *ip, int flags,
- int mission_flags, int *tech)
+ int mission_flags)
{
struct emp_qelem *qp;
struct emp_qelem *next;
struct plist *plp;
+ struct plnstr *pp;
- if (*tech == 0)
- *tech = 9999;
for (qp = list->q_forw; qp != list; qp = next) {
next = qp->q_forw;
plp = (struct plist *)qp;
+ pp = &plp->plane;
- if (plp->plane.pln_x != x)
+ if (pp->pln_x != x)
continue;
- if (plp->plane.pln_y != y)
+ if (pp->pln_y != y)
continue;
- if (mission_pln_equip(plp, ip, flags, mission) < 0) {
+ if (CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED)
+ || mission_pln_equip(plp, ip, flags, mission) < 0) {
emp_remque(qp);
free(qp);
continue;
if (plp->pcp->pl_flags & P_I)
mission_flags |= P_I;
}
- if (*tech > plp->plane.pln_tech)
- *tech = plp->plane.pln_tech;
if (!(plp->pcp->pl_flags & P_H))
/* no stealth on this mission */
mission_flags &= ~P_H;
mission_flags &= ~P_MINE;
}
- /*
- * Mob costs for missions are 1/2 normal
- * Not anymore. :)
- */
-/* plp->plane.pln_mobil -= pln_mobcost(dist,&plp->plane,flags)/2;*/
- plp->plane.pln_mobil -= pln_mobcost(dist, &plp->plane, flags);
-
+ pp->pln_flags |= PLN_LAUNCHED;
+ pp->pln_mobil -= pln_mobcost(dist, pp, flags);
+ putplane(pp->pln_uid, pp);
}
return mission_flags;
}
int
mission_pln_equip(struct plist *plp, struct ichrstr *ip, int flags,
- s_char mission)
+ char mission)
{
struct plchrstr *pcp;
struct plnstr *pp;
- int needed;
+ int load, needed;
struct lndstr land;
struct shpstr ship;
struct sctstr sect;
i_type itype;
- int rval;
short *item;
pp = &plp->plane;
return -1;
}
item[I_PETROL] -= pcp->pl_fuel;
- rval = 0;
if (!(flags & P_F)) {
+ load = pln_load(pp);
itype = I_NONE;
needed = 0;
switch (mission) {
- case 's':
- case 'p':
+ case 's': /* strategic bomb */
+ case 'p': /* pinpoint bomb */
if (pp->pln_nuketype == -1) {
itype = I_SHELL;
- needed = pp->pln_load;
+ needed = load;
}
break;
- case 't':
- if ((pcp->pl_flags & P_C) == 0 || ip == 0)
- break;
- itype = ip->i_uid;
- needed = (pp->pln_load * 2) / ip->i_lbs;
- break;
- case 'd':
+ case 't': /* transport */
+ case 'd': /* drop */
if ((pcp->pl_flags & P_C) == 0 || ip == 0)
break;
itype = ip->i_uid;
- needed = (pp->pln_load * 2) / ip->i_lbs;
+ needed = (load * 2) / ip->i_lbs;
break;
- case 'a':
+ case 'a': /* paradrop */
if ((pcp->pl_flags & (P_V | P_C)) == 0)
break;
itype = I_MILIT;
- needed = pp->pln_load / ip->i_lbs;
- break;
- case 'n':
- if (pp->pln_nuketype == -1)
- rval = -1;
+ needed = load / ip->i_lbs;
break;
case 'i': /* missile interception */
- if (pp->pln_load) {
+ if (load) {
itype = I_SHELL;
- needed = pp->pln_load;
+ needed = load;
}
break;
+ case 'r': /* reconnaissance */
+ case 0: /* plane interception */
+ break;
default:
+ CANT_REACH();
break;
}
- if (rval < 0 || (itype != I_NONE && needed <= 0)) {
+ if (itype != I_NONE && needed <= 0)
return -1;
- }
if (itype != I_NONE) {
if (itype == I_SHELL && item[itype] < needed)
item[itype] += supply_commod(plp->plane.pln_own,
putland(land.lnd_uid, &land);
else
putsect(§);
- return rval;
+ return 0;
}
/*
static int
air_damage(struct emp_qelem *bombers, coord x, coord y, int mission,
- natid victim, s_char *s, int hardtarget)
+ natid victim, char *s, int hardtarget)
{
struct emp_qelem *qp;
struct plist *plp;
}
/* Now, even though we missed, the bombs
land somewhere. */
- collateral_damage(x, y, newdam, bombers);
+ collateral_damage(x, y, newdam);
}
/* use up missiles */
- if (plp->pcp->pl_flags & P_M) {
- makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x,
- pp->pln_y);
- pp->pln_own = 0;
- }
+ if (plp->pcp->pl_flags & P_M)
+ pp->pln_effic = 0;
}
return dam;
struct emp_qelem *esc_list)
{
int dam = 0, cn;
- int mission_flags, tech, combat = 0, rel, dist, z;
+ int mission_flags, combat = 0, rel, dist, z;
struct emp_qelem *qp, interceptors, airp, i, empty, *next;
struct plist *plp;
struct genlist *glp;
- struct genitem *gp;
+ struct empobj *gp;
struct genlist mi[MAXNOC];
char buf[512];
char *path;
next = qp->q_forw;
glp = (struct genlist *)qp;
gp = glp->thing;
+ if (CANT_HAPPEN(gp->ef_type != EF_PLANE))
+ break;
dist = mapdist(x, y, gp->x, gp->y);
for (qp = interceptors.q_forw; qp != (&interceptors);
qp = qp->q_forw)
tcount++;
- tcount -= (count * 2);
+ tcount -= count * 2;
/* Just in case there are more incoming than we have */
if (tcount < 0)
tcount = 0;
/* Split off the interceptors at this base into i */
divide(&interceptors, &i, air->x, air->y);
- tech = 0;
mission_flags = 0;
mission_flags |= P_X; /* stealth (shhh) */
/* gets turned off if not all choppers */
continue;
}
mission_flags =
- mission_pln_arm(&i, air->x, air->y, 2 * dist, 'r', 0, P_F,
- mission_flags, &tech);
+ mission_pln_arm(&i, air->x, air->y, 2 * dist, 0, 0, P_F,
+ mission_flags);
/* Did we run out of interceptors? */
if (QEMPTY(&i))
}
path = BestAirPath(buf, air->x, air->y, x, y);
- if (CANT_HAPPEN(!path))
+ if (CANT_HAPPEN(!path)) {
+ pln_put(&i);
continue;
+ }
wu(0, cn, "Flying %s mission from %s\n",
mission_name(MI_AIR_DEFENSE), xyas(air->x, air->y, cn));
if (air->own && (air->own != cn)) {
/* Now, fly the planes to the sector */
emp_initque(&empty);
ac_encounter(&i, &empty, air->x, air->y,
- path, mission_flags, 1, bomb_list, esc_list);
+ path, mission_flags, 1);
/* If none made it, continue */
if (QEMPTY(&i))
pln_put(&i);
}
+ if (CANT_HAPPEN(!QEMPTY(&interceptors)))
+ pln_put(&interceptors);
}
/* We have to free all of these, if they are still there, otherwise they get