/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2016, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2021, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure, Markus Armbruster
*
* Empire is free software: you can redistribute it and/or modify
* Known contributors to this file:
* Ken Stevens, 1995
* Steve McClure, 1996-2000
- * Markus Armbruster, 2006-2015
+ * Markus Armbruster, 2006-2021
*/
#include <config.h>
y = com->y;
break;
case EF_LAND:
- if (!getland(com->lnd_uid, &land) || !land.lnd_own) {
+ if (!getland(com->lnd_uid, &land) || !land.lnd_own
+ || land.lnd_ship >= 0 || land.lnd_land >= 0) {
if (isdef)
pr("Land unit #%d is not in the same sector!\n",
com->lnd_uid);
while (nxtitem(&ni, &land)) {
if (land.lnd_own != player->cnum)
continue;
- if (land.lnd_effic < LAND_MINEFF)
+ if (!land.lnd_own)
continue;
if (land_answer[(int)land.lnd_army] == 'N')
continue;
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;
}
continue;
if (def->type == EF_SECTOR && land.lnd_land >= 0)
continue;
+ if (def->type == EF_SECTOR && (lchr[land.lnd_type].l_flags & L_SPY))
+ continue;
if (def->type == EF_SHIP && land.lnd_ship != def->shp_uid)
continue;
if (def->type == EF_LAND && land.lnd_land != def->lnd_uid)
intelligence_report(player->cnum, &land, a_spy,
"Scouts report defending unit:");
llp = lnd_insque(&land, list);
- llp->supplied = lnd_supply_all(&land);
+ llp->supplied = lnd_supply_all(&llp->unit.land);
llp->mobil = 0.0;
llp->x = llp->unit.land.lnd_x;
llp->y = llp->unit.land.lnd_y;
llp->eff = llp->unit.land.lnd_effic;
- if (lnd_spyval(&land) > *d_spyp)
- *d_spyp = lnd_spyval(&land);
+ if (lnd_spyval(&llp->unit.land) > *d_spyp)
+ *d_spyp = lnd_spyval(&llp->unit.land);
}
}
struct emp_qelem *qp, *next;
struct ulist *llp;
int n, w;
+ double att_val;
/*
* first, total the attacking mil
llp = (struct ulist *)qp;
if (check && !get_oland(combat_mode, llp))
continue;
+ att_val = attack_val(combat_mode, &llp->unit.land);
+ if (check && att_val < 1.0) {
+ /*
+ * No offensive strength, and fighting hasn't even begun.
+ * 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);
+ continue;
+ }
if (combat_mode == A_ATTACK) {
w = -1;
for (n = 0; n <= off->last; ++n) {
lnd_put_one(llp);
continue;
}
- ototal += attack_val(combat_mode, &llp->unit.land) *
- att_combat_eff(off + w);
- } else {
- ototal += attack_val(combat_mode, &llp->unit.land);
+ att_val *= att_combat_eff(off + w);
}
+ ototal += att_val;
}
ototal *= osupport;
get_dland(struct combat *def, struct ulist *llp)
{
struct lndstr *lp = &llp->unit.land;
- char buf[512];
getland(llp->unit.land.lnd_uid, lp);
- if (lp->lnd_effic < LAND_MINEFF) {
- sprintf(buf, "was destroyed and is no longer a part of the defense");
- lnd_print(llp->unit.land.lnd_own, llp, buf);
+ if (lp->lnd_own != def->own) {
+ lnd_print(llp->unit.land.lnd_own, llp,
+ "was destroyed and is no longer a part of the defense");
lnd_put_one(llp);
return 0;
}
pr("- Casualties -\n Yours: %d\n", a_cas);
pr(" Theirs: %d\n", d_cas);
- pr("Papershuffling ... %.1f B.T.U\n", (d_cas + a_cas) * 0.15);
+ pr("Paper-shuffling ... %.1f BTU\n", (d_cas + a_cas) * 0.15);
player->btused += (int)((d_cas + a_cas) * 0.015 + 0.5);
if (success) {
move_in_land(A_ATTACK, off, olist, def);
}
-/* 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)
+void
+att_move_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];
- if (QEMPTY(olist))
- return;
for (qp = olist->q_forw; qp != olist; qp = next) {
next = qp->q_forw;
llp = (struct ulist *)qp;
else
llp->unit.land.lnd_ship = -1;
}
- if (QEMPTY(olist))
- return;
+}
+
+/* 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 (opt_INTERDICT_ATT) {
lnd_sweep(olist, 0, 0, player->cnum);
} else {
sprintf(buf, "boards %s", prcom(0, def));
}
- if (QEMPTY(olist))
- return;
+
for (qp = olist->q_forw; qp != olist; qp = next) {
next = qp->q_forw;
llp = (struct ulist *)qp;
lnd_print(player->cnum, llp, buf);
}
- if (QEMPTY(olist))
- return;
+
lnd_put(olist);
}