assault: Make spies "sneaking ashore" use mobility and hit mines

Assaulting a foreign sector with nothing but spies is special: the
spies sneak ashore.  It is, however, more special than it should be:
the spies use no mobility and ignore landmines.  They do use mobility
and hit landmines in other assaults.  Assaulting your own sector with
nothing but spies is more costly and more risky than assaulting a
foreign one.  This makes no sense.  Has been that way since spies were
added in 4.0.0.

It's that way because sneaking ashore uses its own code to move the
spies instead of move_in_land() via att_move_in_off().  It can't use
move_in_land(), because that prints an unwanted "now occupies"
message, and destroys the list of assaulting units, which we still
need to catch and shoot spies.

Factor the code to move attacking land units to the target sector out
of move_in_land() into att_move_land(), and use that for sneaking
ashore.  This makes the spies use mobility and hit landmines even when
they sneak.

Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
Markus Armbruster 2016-07-23 23:18:06 +02:00
parent 36e3caf97e
commit 9f851c9f03
Notes: Markus Armbruster 2017-08-14 19:39:26 +02:00
Closes bug#250.
3 changed files with 26 additions and 15 deletions

View file

@ -28,6 +28,7 @@
* *
* Known contributors to this file: * Known contributors to this file:
* Ken Stevens, 1995 * Ken Stevens, 1995
* Markus Armbruster, 2005-2016
*/ */
#ifndef COMBAT_H #ifndef COMBAT_H
@ -69,6 +70,8 @@ struct combat {
/* src/lib/subs/attsub.c */ /* src/lib/subs/attsub.c */
extern double att_combat_eff(struct combat *); extern double att_combat_eff(struct combat *);
extern void att_move_land(int, struct combat *, struct emp_qelem *,
struct combat *);
extern void att_move_in_off(int, struct combat *, struct emp_qelem *, extern void att_move_in_off(int, struct combat *, struct emp_qelem *,
struct combat *); struct combat *);
extern int att_combat_init(struct combat *, int); extern int att_combat_init(struct combat *, int);

View file

@ -41,7 +41,8 @@
#include "unit.h" #include "unit.h"
static int only_spies(struct combat[], struct emp_qelem *); static int only_spies(struct combat[], struct emp_qelem *);
static void sneak_ashore(struct emp_qelem *, struct combat *); static void sneak_ashore(struct combat[], struct emp_qelem *,
struct combat *);
int int
assa(void) assa(void)
@ -139,7 +140,7 @@ assa(void)
/* If no attacking forces (i.e. we got here with only spies) /* If no attacking forces (i.e. we got here with only spies)
* then try to sneak on-land. */ * then try to sneak on-land. */
if (only_spies(off, &olist)) { if (only_spies(off, &olist)) {
sneak_ashore(&olist, def); sneak_ashore(off, &olist, def);
return RET_OK; return RET_OK;
} }
@ -191,7 +192,8 @@ only_spies(struct combat off[], struct emp_qelem *olist)
} }
static void static void
sneak_ashore(struct emp_qelem *olist, struct combat *def) sneak_ashore(struct combat off[], struct emp_qelem *olist,
struct combat *def)
{ {
struct emp_qelem *qp; struct emp_qelem *qp;
struct ulist *llp; struct ulist *llp;
@ -200,15 +202,14 @@ sneak_ashore(struct emp_qelem *olist, struct combat *def)
pr("Trying to sneak on shore...\n"); pr("Trying to sneak on shore...\n");
att_move_land(A_ASSAULT, off, olist, def);
for (qp = olist->q_forw; qp != olist; qp = qp->q_forw) { for (qp = olist->q_forw; qp != olist; qp = qp->q_forw) {
llp = (struct ulist *)qp; llp = (struct ulist *)qp;
lp = &llp->unit.land; lp = &llp->unit.land;
rel = relations_with(def->own, player->cnum); rel = relations_with(def->own, player->cnum);
if (chance(0.10) || rel == ALLIED || !def->own) { if (chance(0.10) || rel == ALLIED || !def->own) {
pr("%s made it on shore safely.\n", prland(lp)); pr("%s made it on shore safely.\n", prland(lp));
lp->lnd_x = def->x;
lp->lnd_y = def->y;
lp->lnd_ship = -1;
} else { } else {
pr("%s was spotted", prland(lp)); pr("%s was spotted", prland(lp));
if (rel <= HOSTILE) { if (rel <= HOSTILE) {
@ -222,9 +223,6 @@ sneak_ashore(struct emp_qelem *olist, struct combat *def)
cname(player->cnum), xyas(def->x, def->y, cname(player->cnum), xyas(def->x, def->y,
def->own)); def->own));
pr(" but made it ok.\n"); pr(" but made it ok.\n");
lp->lnd_x = def->x;
lp->lnd_y = def->y;
lp->lnd_ship = -1;
} }
} }
} }

View file

@ -2299,15 +2299,12 @@ ask_move_in(struct combat *off, struct emp_qelem *olist,
move_in_land(A_ATTACK, off, olist, def); move_in_land(A_ATTACK, off, olist, def);
} }
/* Move offensive land units to the conquered sector or ship */ void
att_move_land(int combat_mode, struct combat *off, struct emp_qelem *olist,
static void struct combat *def)
move_in_land(int combat_mode, struct combat *off, struct emp_qelem *olist,
struct combat *def)
{ {
struct emp_qelem *qp, *next; struct emp_qelem *qp, *next;
struct ulist *llp; struct ulist *llp;
char buf[512];
for (qp = olist->q_forw; qp != olist; qp = next) { for (qp = olist->q_forw; qp != olist; qp = next) {
next = qp->q_forw; next = qp->q_forw;
@ -2322,6 +2319,19 @@ move_in_land(int combat_mode, struct combat *off, struct emp_qelem *olist,
else else
llp->unit.land.lnd_ship = -1; llp->unit.land.lnd_ship = -1;
} }
}
/* Move offensive land units to the conquered sector or ship */
static void
move_in_land(int combat_mode, struct combat *off, struct emp_qelem *olist,
struct combat *def)
{
struct emp_qelem *qp, *next;
struct ulist *llp;
char buf[512];
att_move_land(combat_mode, off, olist, def);
if (def->type == EF_SECTOR) { if (def->type == EF_SECTOR) {
if (opt_INTERDICT_ATT) { if (opt_INTERDICT_ATT) {