/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2010, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
* Known contributors to this file:
* Ken Stevens, 1995
* Steve McClure, 1996-2000
+ * Markus Armbruster, 2004-2009
*/
#include <config.h>
#include "xy.h"
int
-msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
- int snews_item, char *what, coord x, coord y, int victim)
+msl_launch(struct plnstr *pp, int type, char *what, coord x, coord y,
+ natid victim, int *sublaunchp)
{
- int hit;
struct shpstr ship;
struct sctstr sect;
int sublaunch = 0;
- struct plchrstr *pcp = plchr + pp->pln_type;
- int hitchance;
char *from;
int dam;
prplane(pp),
cname(victim),
what,
- (type == EF_SHIP || type == EF_PLANE) ? "in " : "",
+ type != EF_SECTOR ? "in " : "",
xyas(x, y, pp->pln_own));
mpr(pp->pln_own, "\tLaunching from ");
if (pp->pln_ship >= 0) {
shipdamage(&ship, dam);
putship(ship.shp_uid, &ship);
} else {
- pr("Explosion damages %s %d%%",
+ pr("Explosion damages %s %d%%\n",
xyas(pp->pln_x, pp->pln_y, pp->pln_own), dam);
getsect(pp->pln_x, pp->pln_y, §);
sectdamage(§, dam);
putsect(§);
}
}
- return 0;
+ return -1;
}
CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED);
putplane(pp->pln_uid, pp);
mpr(pp->pln_own, "\tSHWOOOOOSH! Missile launched!\n");
- if (pcp->pl_flags & P_T)
+ if (type != EF_PLANE)
mpr(victim, "Incoming %s missile sighted at %s...\n",
sublaunch ? "sub-launched" : cname(pp->pln_own),
xyas(x, y, victim));
- if ((pcp->pl_flags & P_T && !(pcp->pl_flags & P_MAR))) {
- if (msl_intercept(x, y, pp->pln_own, pcp->pl_def,
- sublaunch, P_N, P_O)) {
- return 0;
- }
+ if (type == EF_SECTOR || type == EF_LAND) {
+ if (msl_abm_intercept(pp, x, y, sublaunch))
+ return -1;
}
- if (pcp->pl_flags & P_MAR) {
- if (shp_missile_defense(x, y, pp->pln_own, pcp->pl_def)) {
- return 0;
+ if (type == EF_SHIP) {
+ if (shp_missile_defense(x, y, pp->pln_own, pln_def(pp))) {
+ return -1;
}
}
+ if (sublaunchp)
+ *sublaunchp = sublaunch;
+ return 0;
+}
+
+int
+msl_hit(struct plnstr *pp, int hardtarget, int type,
+ int news_item, int snews_item, int sublaunch, natid victim)
+{
+ int hitchance, hit;
+
if (nuk_on_plane(pp) >= 0) {
mpr(pp->pln_own, "\tArming nuclear warheads...\n");
hit = 1;
hit ? "HIT!" : "miss");
}
- if (pcp->pl_flags & P_T)
+ if (type != EF_PLANE)
mpr(victim, "...Incoming %s missile %s\n",
sublaunch ? "" : cname(pp->pln_own),
hit ? "HIT!\n" : "missed\n");
}
}
-int
-msl_intercept(coord x, coord y, natid bombown, int hardtarget,
- int sublaunch, int wantflags, int nowantflags)
+static int
+msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch,
+ struct emp_qelem *irvlist, char *att_name, char *def_name,
+ int news_item)
{
struct plnstr *pp;
- struct plchrstr *pcp;
- struct sctstr sect;
- struct emp_qelem *irvlist;
- struct emp_qelem foo;
struct emp_qelem *intlist;
struct emp_qelem intfoo;
struct emp_qelem *qp;
struct plist *ip;
int icount = 0;
short destroyed;
- char *att_name;
- char *def_name;
- int news_item;
- char *who = sublaunch ? "" : cname(bombown);
-
- getsect(x, y, §);
- if (wantflags == P_O && !nowantflags) {
- att_name = "satellite";
- def_name = "a-sat missile";
- news_item = N_SAT_KILL;
- CANT_HAPPEN(sublaunch);
- mpr(sect.sct_own, "%s has positioned a satellite over %s\n",
- cname(bombown), xyas(x, y, sect.sct_own));
- } else if (wantflags == P_N && nowantflags == P_O) {
- att_name = "warhead";
- def_name = "abm";
- news_item = sublaunch ? N_NUKE_SSTOP : N_NUKE_STOP;
- } else {
- att_name = "elephant";
- def_name = "tomato"; /* heh -KHS */
- news_item = N_NUKE_STOP;
- }
- irvlist = &foo;
+ char *who = sublaunch ? "" : cname(msl->pln_own);
- /* get all hostile abms in range */
- msl_sel(irvlist, x, y, bombown, wantflags, nowantflags, 0);
intlist = &intfoo;
emp_initque(intlist);
/* First choose interceptors belonging to the target sector */
next = qp->q_forw;
ip = (struct plist *)qp;
pp = &ip->plane;
- if (pp->pln_own != sect.sct_own)
+ if (pp->pln_own != sp->sct_own)
continue;
- pcp = ip->pcp;
if (mission_pln_equip(ip, NULL, 'i') < 0) {
emp_remque(qp);
free(qp);
next = qp->q_forw;
ip = (struct plist *)qp;
pp = &ip->plane;
- pcp = ip->pcp;
if (mission_pln_equip(ip, NULL, 'i') < 0) {
emp_remque(qp);
free(qp);
free(qp);
}
if (icount == 0) {
- mpr(sect.sct_own, "No %ss launched to intercept.\n", def_name);
+ mpr(sp->sct_own, "No %ss launched to intercept.\n", def_name);
return 0;
}
qp = intlist->q_forw;
ip = (struct plist *)qp;
pp = &ip->plane;
- pcp = ip->pcp;
- mpr(bombown, "%s %s launched in defense!\n",
+ mpr(msl->pln_own, "%s %s launched in defense!\n",
cname(pp->pln_own), def_name);
- if (sect.sct_own == pp->pln_own) {
- mpr(sect.sct_own, "%s launched to intercept %s %s!\n",
+ if (sp->sct_own == pp->pln_own) {
+ mpr(sp->sct_own, "%s launched to intercept %s %s!\n",
def_name, who, att_name);
} else {
- mpr(sect.sct_own,
+ mpr(sp->sct_own,
"%s launched an %s to intercept the %s %s!\n",
cname(pp->pln_own), def_name, who, att_name);
mpr(pp->pln_own,
"%s launched to intercept %s %s arcing towards %s territory!\n",
- def_name, who, att_name, cname(sect.sct_own));
+ def_name, who, att_name, cname(sp->sct_own));
}
- if (msl_hit(pp, hardtarget, EF_PLANE, news_item, news_item,
- att_name, x, y, bombown)) {
- mpr(bombown, "%s destroyed by %s %s!\n",
+ if (msl_launch(pp, EF_PLANE, att_name, sp->sct_x, sp->sct_y,
+ msl->pln_own, NULL) >= 0
+ && msl_hit(pp, pln_def(msl), EF_PLANE, 0, 0, 0, msl->pln_own)) {
+ mpr(msl->pln_own, "%s destroyed by %s %s!\n",
att_name, cname(pp->pln_own), def_name);
- mpr(sect.sct_own, "%s %s intercepted!\n", who, att_name);
- if (sect.sct_own != pp->pln_own)
+ mpr(sp->sct_own, "%s %s intercepted!\n", who, att_name);
+ if (sp->sct_own != pp->pln_own)
mpr(pp->pln_own, "%s %s intercepted!\n", who, att_name);
+ if (sublaunch)
+ nreport(pp->pln_own, news_item, 0, 1);
+ else
+ nreport(pp->pln_own, news_item, msl->pln_own, 1);
destroyed = 1;
}
/* zap the missile */
if (destroyed)
return 1;
if (icount) {
- mpr(bombown, "%s made it through %s defenses!\n",
+ mpr(msl->pln_own, "%s made it through %s defenses!\n",
att_name, def_name);
- mpr(sect.sct_own, "%s made it through %s defenses!\n",
+ mpr(sp->sct_own, "%s made it through %s defenses!\n",
att_name, def_name);
}
return 0;
}
-/* Keep launching missiles on list until mindam damage has been done */
int
-msl_launch_mindam(struct emp_qelem *list, coord x, coord y, int hardtarget,
- int type, int mindam, char *whatp, int victim)
+msl_abm_intercept(struct plnstr *msl, coord x, coord y, int sublaunch)
{
- struct emp_qelem *qp;
- struct emp_qelem *next;
- struct plist *plp;
- int newdam, dam = 0;
- int news_item;
- int snews_item;
+ struct sctstr sect;
+ struct emp_qelem irvlist;
- if (type == EF_SHIP) {
- news_item = N_SHP_MISS;
- snews_item = N_SHP_SMISS;
- } else if (type == EF_LAND) {
- news_item = N_LND_MISS;
- snews_item = N_LND_SMISS;
- } else {
- news_item = N_SCT_MISS;
- snews_item = N_SCT_SMISS;
- }
+ getsect(x, y, §);
+ msl_sel(&irvlist, x, y, msl->pln_own, P_N, P_O, 0);
+ return msl_intercept(msl, §, sublaunch,
+ &irvlist, "warhead", "abm",
+ sublaunch ? N_NUKE_SSTOP : N_NUKE_STOP);
+}
- for (qp = list->q_back; qp != list && dam < mindam;
- qp = next) {
- next = qp->q_back;
- plp = (struct plist *)qp;
+int
+msl_asat_intercept(struct plnstr *msl, coord x, coord y)
+{
+ struct sctstr sect;
+ struct emp_qelem irvlist;
- if (mission_pln_equip(plp, NULL, 'p') >= 0) {
- if (msl_hit(&plp->plane,
- hardtarget, type, news_item, snews_item,
- whatp, x, y, victim)) {
- newdam = pln_damage(&plp->plane, 'p', 1);
- dam += newdam;
-#if 0
- /*
- * FIXME want collateral damage on miss, but we get here
- * too when launch fails or missile is intercepted
- */
- } else {
- /* Missiles that miss have to hit somewhere! */
- newdam = pln_damage(&plp->plane, 'p', 0);
- collateral_damage(x, y, newdam);
-#endif
- }
- plp->plane.pln_effic = 0;
- putplane(plp->plane.pln_uid, &plp->plane);
- emp_remque(qp);
- free(qp);
- }
- }
- return dam;
+ getsect(x, y, §);
+ mpr(sect.sct_own, "%s has positioned a satellite over %s\n",
+ cname(msl->pln_own), xyas(x, y, sect.sct_own));
+ msl_sel(&irvlist, x, y, msl->pln_own, P_O, 0, 0);
+ return msl_intercept(msl, §, 0,
+ &irvlist, "satellite", "a-sat missile",
+ N_SAT_KILL);
}