From fd894d9864423e6a3241c84dbce67ec86880ee2d Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 11 Oct 2009 12:04:16 -0400 Subject: [PATCH] Fix and enable collateral damage for missing missiles Collateral damage was disabled, because after msl_hit() reported a miss, the missile may or may not have reached the target. Fix by splitting msl_launch() off msl_hit(). Drop the disabled collateral damage code for sector targets, because sectors can't be missed. Enable it for ships and land units. Since msl_launch() returns whether the missile is sub-launched, drop launch_missile() parameter sublaunch, and simplify its caller. --- include/prototypes.h | 5 +++-- src/lib/commands/laun.c | 50 ++++++++++++++++------------------------- src/lib/subs/lndsub.c | 16 +++++-------- src/lib/subs/mission.c | 27 +++++++++------------- src/lib/subs/mslsub.c | 30 +++++++++++++++++-------- src/lib/subs/shpsub.c | 19 ++++++---------- 6 files changed, 66 insertions(+), 81 deletions(-) diff --git a/include/prototypes.h b/include/prototypes.h index 326cf46c9..94b838333 100644 --- a/include/prototypes.h +++ b/include/prototypes.h @@ -492,8 +492,9 @@ extern int move_ground(struct sctstr *, struct sctstr *, int, int *); extern int fly_map(coord, coord); /* mslsub.c */ -extern int msl_hit(struct plnstr *, int, int, int, int, char *, - coord, coord, int); +extern int msl_launch(struct plnstr *, int, char *, coord, coord, natid, + int *); +extern int msl_hit(struct plnstr *, int, int, int, int, int, natid); extern void msl_sel(struct emp_qelem *, coord, coord, natid, int, int, int); extern int msl_abm_intercept(struct plnstr *, coord, coord, int); diff --git a/src/lib/commands/laun.c b/src/lib/commands/laun.c index b339de8d6..1efe0e0e5 100644 --- a/src/lib/commands/laun.c +++ b/src/lib/commands/laun.c @@ -47,7 +47,7 @@ #include "ship.h" static int launch_as(struct plnstr *pp); -static int launch_missile(struct plnstr *pp, int sublaunch); +static int launch_missile(struct plnstr *pp); static int launch_sat(struct plnstr *pp); static int msl_equip(struct plnstr *, char); @@ -59,8 +59,6 @@ laun(void) { struct nstr_item nstr; struct plnstr plane; - struct shpstr ship; - int sublaunch; struct plchrstr *pcp; int retval, gone; @@ -101,17 +99,11 @@ laun(void) } if (!pln_airbase_ok(&plane, 1, 1)) continue; - sublaunch = 0; - if (plane.pln_ship >= 0) { - getship(plane.pln_ship, &ship); - if (mchr[(int)ship.shp_type].m_flags & M_SUB) - sublaunch = 1; - } pr("%s at %s; range %d, eff %d%%\n", prplane(&plane), xyas(plane.pln_x, plane.pln_y, player->cnum), plane.pln_range, plane.pln_effic); if (!(pcp->pl_flags & P_O)) { - retval = launch_missile(&plane, sublaunch); + retval = launch_missile(&plane); gone = 1; } else if ((pcp->pl_flags & (P_M | P_O)) == (P_M | P_O)) { retval = launch_as(&plane); @@ -160,8 +152,10 @@ launch_as(struct plnstr *pp) } if (msl_equip(pp, 'i') < 0) return RET_FAIL; - if (msl_hit(pp, pln_def(&plane), EF_PLANE, 0, 0, - prplane(&plane), plane.pln_x, plane.pln_y, plane.pln_own)) { + if (msl_launch(pp, EF_PLANE, prplane(&plane), + plane.pln_x, plane.pln_y, plane.pln_own, NULL) < 0) + return RET_OK; + if (msl_hit(pp, pln_def(&plane), EF_PLANE, 0, 0, 0, plane.pln_own)) { pr("Satellite shot down\n"); mpr(plane.pln_own, "%s anti-sat destroyed %s over %s\n", cname(player->cnum), prplane(&plane), @@ -175,16 +169,15 @@ launch_as(struct plnstr *pp) /* * Launch missile PP. - * If SUBLAUNCH, it's sub-launched. * Return RET_OK if launched (even when missile explodes), * else RET_SYN or RET_FAIL. */ static int -launch_missile(struct plnstr *pp, int sublaunch) +launch_missile(struct plnstr *pp) { struct plchrstr *pcp = plchr + pp->pln_type; coord sx, sy; - int n, dam; + int n, dam, sublaunch; char *cp; struct mchrstr *mcp; struct shpstr target_ship; @@ -250,18 +243,12 @@ launch_missile(struct plnstr *pp, int sublaunch) return RET_OK; } } - if (!msl_hit(pp, SECT_HARDTARGET, EF_SECTOR, N_SCT_MISS, - N_SCT_SMISS, "sector", sx, sy, sect.sct_own)) { -#if 0 - /* - * FIXME want collateral damage on miss, but we get here - * too when launch fails or missile is intercepted - */ - dam = pln_damage(pp, 's', 0); - collateral_damage(sect.sct_x, sect.sct_y, dam, 0); -#endif + if (msl_launch(pp, EF_SECTOR, "sector", sx, sy, sect.sct_own, + &sublaunch) < 0) return RET_OK; - } + if (!msl_hit(pp, SECT_HARDTARGET, EF_SECTOR, + N_SCT_MISS, N_SCT_SMISS, sublaunch, sect.sct_own)) + CANT_REACH(); if (getnuke(nuk_on_plane(pp), &nuke)) detonate(&nuke, sx, sy, pp->pln_flags & PLN_AIRBURST); else { @@ -285,15 +272,16 @@ launch_missile(struct plnstr *pp, int sublaunch) } else { if (msl_equip(pp, 'p') < 0) return RET_FAIL; + if (msl_launch(pp, EF_SHIP, prship(&target_ship), + target_ship.shp_x, target_ship.shp_y, + target_ship.shp_own, &sublaunch) < 0) + return RET_OK; if (!msl_hit(pp, shp_hardtarget(&target_ship), EF_SHIP, - N_SHP_MISS, N_SHP_SMISS, prship(&target_ship), - target_ship.shp_x, target_ship.shp_y, + N_SHP_MISS, N_SHP_SMISS, sublaunch, target_ship.shp_own)) { pr("splash\n"); -#if 0 /* FIXME see above */ dam = pln_damage(pp, 'p', 0); - collateral_damage(target_ship.shp_x, target_ship.shp_y, dam, 0); -#endif + collateral_damage(target_ship.shp_x, target_ship.shp_y, dam); return RET_OK; } dam = pln_damage(pp, 'p', 1); diff --git a/src/lib/subs/lndsub.c b/src/lib/subs/lndsub.c index 98fb636cd..884d5b14d 100644 --- a/src/lib/subs/lndsub.c +++ b/src/lib/subs/lndsub.c @@ -720,7 +720,7 @@ lnd_missile_interdiction(struct emp_qelem *list, coord newx, coord newy, { int mindam = lnd_count(list) * 20; int hardtarget = lnd_easiest_target(list); - int dam, newdam; + int dam, newdam, sublaunch; struct plist *plp; struct emp_qelem msl_list, *qp, *newqp; @@ -732,22 +732,18 @@ lnd_missile_interdiction(struct emp_qelem *list, coord newx, coord newy, plp = (struct plist *)qp; if (dam < mindam && mission_pln_equip(plp, NULL, 'p') >= 0) { + if (msl_launch(&plp->plane, EF_LAND, "troops", + newx, newy, victim, &sublaunch) < 0) + goto use_up_msl; if (msl_hit(&plp->plane, hardtarget, EF_LAND, - N_LND_MISS, N_LND_SMISS, - "troops", newx, newy, victim)) { + N_LND_MISS, N_LND_SMISS, sublaunch, 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(newx, newy, newdam); -#endif } + use_up_msl: plp->plane.pln_effic = 0; putplane(plp->plane.pln_uid, &plp->plane); } diff --git a/src/lib/subs/mission.c b/src/lib/subs/mission.c index 8012db2c0..d37135f62 100644 --- a/src/lib/subs/mission.c +++ b/src/lib/subs/mission.c @@ -389,7 +389,7 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, struct plchrstr *pcp; int dam = 0, dam2; natid plane_owner = 0; - int md, range, air_dam; + int md, range, air_dam, sublaunch; double hitchance, vrange; int targeting_ships = *s == 's'; /* "subs" or "ships" FIXME gross! */ @@ -562,22 +562,15 @@ perform_mission(coord x, coord y, natid victim, struct emp_qelem *list, && !CANT_HAPPEN(hardtarget != SECT_HARDTARGET || (plp->pcp->pl_flags & P_MAR)) && mission_pln_equip(plp, NULL, 'p') >= 0) { - if (msl_hit(&plp->plane, SECT_HARDTARGET, EF_SECTOR, - N_SCT_MISS, N_SCT_SMISS, - "sector", x, y, victim)) { - dam2 = pln_damage(&plp->plane, 'p', 1); - air_dam += dam2; -#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! */ - dam2 = pln_damage(&plp->plane, 'p', 0); - collateral_damage(x, y, dam2); -#endif - } + if (msl_launch(&plp->plane, EF_SECTOR, "sector", x, y, victim, + &sublaunch) < 0) + goto use_up_msl; + if (!msl_hit(&plp->plane, SECT_HARDTARGET, EF_SECTOR, + N_SCT_MISS, N_SCT_SMISS, sublaunch, victim)) + CANT_REACH(); + dam2 = pln_damage(&plp->plane, 'p', 1); + air_dam += dam2; + use_up_msl: plp->plane.pln_effic = 0; putplane(plp->plane.pln_uid, &plp->plane); } diff --git a/src/lib/subs/mslsub.c b/src/lib/subs/mslsub.c index c2b2d728a..30ed82cb2 100644 --- a/src/lib/subs/mslsub.c +++ b/src/lib/subs/mslsub.c @@ -30,6 +30,7 @@ * Known contributors to this file: * Ken Stevens, 1995 * Steve McClure, 1996-2000 + * Markus Armbruster, 2004-2009 */ #include @@ -54,15 +55,13 @@ #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; @@ -108,7 +107,7 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item, putsect(§); } } - return 0; + return -1; } CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED); @@ -123,14 +122,26 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item, if ((pcp->pl_flags & P_T && !(pcp->pl_flags & P_MAR))) { if (msl_abm_intercept(pp, x, y, sublaunch)) - return 0; + return -1; } if (pcp->pl_flags & P_MAR) { if (shp_missile_defense(x, y, pp->pln_own, pln_def(pp))) { - return 0; + 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) +{ + struct plchrstr *pcp = plchr + pp->pln_type; + int hitchance, hit; + if (nuk_on_plane(pp) >= 0) { mpr(pp->pln_own, "\tArming nuclear warheads...\n"); hit = 1; @@ -294,8 +305,9 @@ msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch, def_name, who, att_name, cname(sp->sct_own)); } - if (msl_hit(pp, pln_def(msl), EF_PLANE, 0, 0, - att_name, sp->sct_x, sp->sct_y, msl->pln_own)) { + 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(sp->sct_own, "%s %s intercepted!\n", who, att_name); diff --git a/src/lib/subs/shpsub.c b/src/lib/subs/shpsub.c index c46ea7e79..50e942f78 100644 --- a/src/lib/subs/shpsub.c +++ b/src/lib/subs/shpsub.c @@ -480,7 +480,7 @@ static int shp_missile_interdiction(struct emp_qelem *list, coord newx, coord newy, natid victim) { - int dam; + int dam, sublaunch; int stopping = 0; struct emp_qelem msl_list, *qp, *newqp; struct plist *plp; @@ -494,11 +494,12 @@ shp_missile_interdiction(struct emp_qelem *list, coord newx, coord newy, mvs = most_valuable_ship(list, newx, newy); if (mvs && mission_pln_equip(plp, NULL, 'p') >= 0) { + if (msl_launch(&plp->plane, EF_SHIP, prship(&mvs->unit.ship), + newx, newy, victim, &sublaunch) < 0) + goto use_up_msl; if (msl_hit(&plp->plane, - shp_hardtarget(&mvs->unit.ship), - EF_SHIP, N_SHP_MISS, N_SHP_SMISS, - prship(&mvs->unit.ship), - newx, newy, victim)) { + shp_hardtarget(&mvs->unit.ship), EF_SHIP, + N_SHP_MISS, N_SHP_SMISS, sublaunch, victim)) { dam = pln_damage(&plp->plane, 'p', 1); if (dam) { mpr(victim, @@ -507,17 +508,11 @@ shp_missile_interdiction(struct emp_qelem *list, coord newx, coord newy, shp_damage_one(mvs, dam); stopping = 1; } -#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! */ dam = pln_damage(&plp->plane, 'p', 0); collateral_damage(newx, newy, dam); -#endif } + use_up_msl: plp->plane.pln_effic = 0; putplane(plp->plane.pln_uid, &plp->plane); } -- 2.43.0