From 6fd04eabeef7a71ddb3b6f705c68b10d50b6c010 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 24 Jul 2016 14:02:53 +0200 Subject: [PATCH] assault: Don't send spies into combat The server doesn't let you send land units without offensive strength into combat: ask_olist() simply doesn't offer them. Good. However, it needs to offer spies for assault, because assault is how they sneak ashore. To make it offer spies, which have no offensive strength, attack_val() artificially sets their offensive strength to one for assault. Dirt effect: spies fight (and die) in assaults, even though they can't otherwise attack. Lame. Has been that way since spies were added in 4.0.0. Make ask_olist() offer spies regardless of offensive strength when assaulting, and drop the special case from attack_val(). They get offered exactly as before. However, since their offensive strength is now zero, they won't enter actual combat (see the previous commit). Signed-off-by: Markus Armbruster --- info/Spies.t | 3 --- src/lib/subs/attsub.c | 15 +++++++++++---- src/lib/subs/lndsub.c | 22 +++++++--------------- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/info/Spies.t b/info/Spies.t index 36315662..21c2ce7a 100644 --- a/info/Spies.t +++ b/info/Spies.t @@ -22,9 +22,6 @@ shelling, bombing, etc. and take ANY damage at all, they die. Spies may also be snuck on shore via ships using the "assault" command. If you assault a sector using just spies, a 100% spy has a 60% chance of getting caught, which increases to 100% for a 20% spy. -If you mix spies and mil, -the spies must fight just like normal units. And, since any damage they take -kills them, this is very risky usage of spies. .s1 You may locate spies using the "llookout" or the "spy" command. .s1 diff --git a/src/lib/subs/attsub.c b/src/lib/subs/attsub.c index fd36afce..65aac889 100644 --- a/src/lib/subs/attsub.c +++ b/src/lib/subs/attsub.c @@ -1041,7 +1041,14 @@ ask_olist(int combat_mode, struct combat *off, struct combat *def, return; } att_val = attack_val(combat_mode, &land); - if (att_val < 1.0) { + /* + * We need to let spies assault even though they have no + * offensive strength, because assault is how they sneak + * ashore. If this assault turns out to be a fight, they'll + * be removed by get_ototal(). + */ + if (att_val < 1.0 + && !(combat_mode == A_ASSAULT && (lcp->l_flags & L_SPY))) { pr("%s has no offensive strength\n", prland(&land)); continue; } @@ -1245,9 +1252,9 @@ get_ototal(int combat_mode, struct combat *off, struct emp_qelem *olist, if (check && att_val < 1.0) { /* * No offensive strength, and fighting hasn't even begun. - * Since ask_olist() doesn't offer such land units, the - * strength must have been destroyed since then. Leave it - * behind. + * Since ask_olist() doesn't offer such land units, except + * for spies sometimes, it's either a spy, or the strength + * must have been destroyed since then. Leave it behind. */ lnd_print(player->cnum, llp, "has no offensive strength"); lnd_put_one(llp); diff --git a/src/lib/subs/lndsub.c b/src/lib/subs/lndsub.c index bcf183d0..65ecbe2d 100644 --- a/src/lib/subs/lndsub.c +++ b/src/lib/subs/lndsub.c @@ -84,12 +84,6 @@ attack_val(int combat_mode, struct lndstr *lp) lcp = &lchr[(int)lp->lnd_type]; -/* Spies always count as 1 during assaults. If they are the only ones - in the assault, they get to sneak on anyway. */ - - if (lcp->l_flags & L_SPY && combat_mode == A_ASSAULT) - return 1; - men = lp->lnd_item[I_MILIT]; value = men * lnd_att(lp) * lp->lnd_effic / 100.0; @@ -179,16 +173,14 @@ lnd_take_casualty(int combat_mode, struct ulist *llp, int cas) signed char orig; int mob; + if (CANT_HAPPEN(lchr[llp->unit.land.lnd_type].l_flags & L_SPY)) + return 0; + taken = llp->unit.land.lnd_item[I_MILIT]; - /* Spies always die */ - if (lchr[llp->unit.land.lnd_type].l_flags & L_SPY) - llp->unit.land.lnd_effic = 0; - else { - eff_eq = ldround(cas * 100.0 / - lchr[llp->unit.land.lnd_type].l_item[I_MILIT], 1); - llp->unit.land.lnd_effic -= eff_eq; - lnd_submil(&llp->unit.land, cas); - } + eff_eq = ldround(cas * 100.0 / + lchr[llp->unit.land.lnd_type].l_item[I_MILIT], 1); + llp->unit.land.lnd_effic -= eff_eq; + lnd_submil(&llp->unit.land, cas); if (llp->unit.land.lnd_effic < LAND_MINEFF) { sprintf(buf, "dies %s %s!",