/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2006, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure
*
* This program is free software; you can redistribute it and/or modify
*
* ---
*
- * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
- * related information and legal notices. It is expected that any future
- * projects/authors will amend these files as needed.
+ * See files README, COPYING and CREDITS in the root of the source
+ * tree for related information and legal notices. It is expected
+ * that future projects/authors will amend these files as needed.
*
* ---
*
* Steve McClure, 1998-2000
*/
+#include <config.h>
+
#include <math.h>
#include "misc.h"
#include "player.h"
#include "file.h"
-#include "var.h"
#include "sect.h"
#include "path.h"
#include "news.h"
-#include "treaty.h"
#include "nat.h"
#include "xy.h"
#include "land.h"
#include "optlist.h"
#include "prototypes.h"
+static void lnd_mess(char *, struct llist *);
+static int lnd_hit_mine(struct lndstr *, struct lchrstr *);
+
int
attack_val(int combat_mode, struct lndstr *lp)
{
int men;
- int value;
+ double value;
struct lchrstr *lcp;
- if (((int)lp->lnd_effic) < LAND_MINEFF) {
- makelost(EF_LAND, lp->lnd_own, lp->lnd_uid, lp->lnd_x, lp->lnd_y);
- lp->lnd_own = 0;
+ if (lp->lnd_effic < LAND_MINEFF) {
putland(lp->lnd_uid, lp);
return 0;
}
if (lcp->l_flags & L_SPY && combat_mode == A_ASSAULT)
return 1;
- men = total_mil(lp);
-
- value = ldround(((double)men * (double)lp->lnd_att), 1);
-
- value = (int)((double)value * ((double)lp->lnd_effic / 100.0));
+ men = lp->lnd_item[I_MILIT];
+ value = men * lp->lnd_att * lp->lnd_effic / 100.0;
switch (combat_mode) {
case A_ATTACK:
- return value;
+ return (int)value;
case A_ASSAULT:
if (!(lcp->l_flags & L_MARINE))
return (int)(assault_penalty * value);
return (int)(assault_penalty * men);
}
- return value;
+ return (int)value;
}
int
double value;
struct lchrstr *lcp;
- if (((int)lp->lnd_effic) < LAND_MINEFF) {
- makelost(EF_LAND, lp->lnd_own, lp->lnd_uid, lp->lnd_x, lp->lnd_y);
- lp->lnd_own = 0;
+ if (lp->lnd_effic < LAND_MINEFF) {
putland(lp->lnd_uid, lp);
return 0;
}
lcp = &lchr[(int)lp->lnd_type];
- men = total_mil(lp);
+ men = lp->lnd_item[I_MILIT];
- if (men < 0)
- men = 0;
if ((lp->lnd_ship >= 0 || lp->lnd_land >= 0) &&
!(lcp->l_flags & L_MARINE))
return men;
- value = men * lp->lnd_def;
-
- value *=
- ((double)land_mob_max + lp->lnd_harden) / (double)land_mob_max;
- value = (int)((double)value * ((double)lp->lnd_effic / 100.0));
- value = (int)ldround(value, 1);
+ value = men * lp->lnd_def * lp->lnd_effic / 100.0;
+ value *= ((double)land_mob_max + lp->lnd_harden) / land_mob_max;
/* If there are military on the unit, you get at least a 1
man defensive unit, except for spies */
if (value < 1.0 && men > 0 && !(lcp->l_flags & L_SPY))
return 1;
- return (int)(value);
-}
-
-int
-total_mil(struct lndstr *lp)
-{
- struct lchrstr *lcp;
- double men;
-
- lcp = &lchr[(int)lp->lnd_type];
-
- men = lnd_getmil(lp);
-/* men *= ((double)lp->lnd_effic)/100.0;*/
-
- return ldround(men, 1);
+ return (int)value;
}
void
-lnd_print(struct llist *llp, s_char *s)
+lnd_print(struct llist *llp, char *s)
{
if (llp->land.lnd_own == player->cnum)
pr("%s %s\n", prland(&llp->land), s);
}
void
-lnd_delete(struct llist *llp, s_char *s)
+lnd_delete(struct llist *llp, char *s)
{
if (s)
lnd_print(llp, s);
putland(llp->land.lnd_uid, &llp->land);
emp_remque((struct emp_qelem *)llp);
- free((s_char *)llp);
+ free(llp);
}
int
coord bx, by;
struct sctstr sect;
int ret_chance;
- s_char buf[1024];
+ char buf[1024];
int taken;
int nowhere_to_go = 0;
struct sctstr rsect;
- double mobcost;
- s_char orig;
+ double mobcost, bmcost;
+ signed char orig;
int mob;
-
-
- taken = lnd_getmil(&(llp->land));
+ taken = llp->land.lnd_item[I_MILIT];
/* Spies always die */
if (llp->lcp->l_flags & L_SPY) {
eff_eq = 100;
llp->land.lnd_effic = 0;
} else {
- eff_eq =
- ldround((((double)cas * 100.0) / (double)llp->lcp->l_mil), 1);
+ eff_eq = ldround(cas * 100.0 / llp->lcp->l_mil, 1);
llp->land.lnd_effic -= eff_eq;
- lnd_submil(&(llp->land), cas);
+ lnd_submil(&llp->land, cas);
}
if (llp->land.lnd_effic < LAND_MINEFF) {
sprintf(buf, "dies %s %s!",
- combat_mode ? att_mode[combat_mode] : (s_char *)
- "defending", xyas(llp->land.lnd_x, llp->land.lnd_y,
- llp->land.lnd_own));
+ combat_mode ? att_mode[combat_mode] : "defending",
+ xyas(llp->land.lnd_x, llp->land.lnd_y, llp->land.lnd_own));
lnd_delete(llp, buf);
/* Since we killed the unit, we killed all the mil on it */
return taken;
} else {
/* Ok, now, how many did we take off? (sould be the diff) */
- taken = taken - lnd_getmil(&(llp->land));
+ taken = taken - llp->land.lnd_item[I_MILIT];
}
if (llp->land.lnd_effic >= llp->land.lnd_retreat)
continue;
if (sect.sct_type == SCT_MOUNT)
continue;
+ mobcost = lnd_mobcost(&llp->land, &rsect);
+ if (mobcost < 0)
+ continue;
++nowned;
civs = sect.sct_item[I_CIVIL];
if (civs > biggest) {
biggest = civs;
bx = sect.sct_x;
by = sect.sct_y;
+ bmcost = mobcost;
}
}
if (!nowned)
llp->land.lnd_x = bx;
llp->land.lnd_y = by;
getsect(bx, by, &rsect);
- mobcost = lnd_mobcost(&llp->land, &rsect, MOB_ROAD);
- mob = llp->land.lnd_mobil - (int)mobcost;
+ mob = llp->land.lnd_mobil - (int)bmcost;
if (mob < -127)
mob = -127;
orig = llp->land.lnd_mobil;
- llp->land.lnd_mobil = (s_char)mob;
+ llp->land.lnd_mobil = (signed char)mob;
if (llp->land.lnd_mobil > orig)
- llp->land.lnd_mobil = (-127);
+ llp->land.lnd_mobil = -127;
sprintf(buf, "retreats at %d%% efficiency to %s!",
llp->land.lnd_effic,
xyas(bx, by, llp->land.lnd_own));
new = llp->land.lnd_mobil - mcost;
if (new < -127)
new = -127;
- llp->land.lnd_mobil = (s_char)new;
+ llp->land.lnd_mobil = (signed char)new;
}
}
-int
-lnd_getmil(struct lndstr *lp)
-{
- return lp->lnd_item[I_MILIT];
-}
void
lnd_submil(struct lndstr *lp, int num)
lnd_spyval(struct lndstr *lp)
{
if (lchr[(int)lp->lnd_type].l_flags & L_RECON)
- return (lp->lnd_spy * (lp->lnd_effic / 100.0)) + 2;
+ return lp->lnd_spy * (lp->lnd_effic / 100.0) + 2;
else
- return (lp->lnd_spy * (lp->lnd_effic / 100.0));
+ return lp->lnd_spy * (lp->lnd_effic / 100.0);
}
int
intelligence_report(int destination, struct lndstr *lp, int spy,
- s_char *mess)
+ char *mess)
{
struct lchrstr *lcp;
- s_char buf1[80], buf2[80], buf3[80];
+ char buf1[80], buf2[80], buf3[80];
double estimate = 0.0; /* estimated defense value */
if (destination == 0)
memset(buf1, 0, sizeof(buf1));
memset(buf2, 0, sizeof(buf2));
memset(buf3, 0, sizeof(buf3));
- if (chance((double)(spy + lp->lnd_vis) / 10.0)) {
+ if (chance((spy + lp->lnd_vis) / 10.0)) {
if (destination == player->cnum)
pr("%s %s", mess, prland(lp));
else
sprintf(buf1, "%s %s", mess, prland(lp));
- estimate = lnd_getmil(lp);
-
- if (chance((double)(spy + lp->lnd_vis) / 20.0)) {
+ estimate = lp->lnd_item[I_MILIT];
+ if (chance((spy + lp->lnd_vis) / 20.0)) {
if (destination == player->cnum)
- pr(" (eff %d, mil %d", roundintby(lp->lnd_effic, 5),
- roundintby(lnd_getmil(lp), 10));
+ pr(" (eff %d, mil %d",
+ roundintby(lp->lnd_effic, 5),
+ roundintby(lp->lnd_item[I_MILIT], 10));
else
sprintf(buf2, " (eff %d, mil %d",
roundintby(lp->lnd_effic, 5),
- roundintby(lnd_getmil(lp), 10));
- estimate = lnd_getmil(lp) * lp->lnd_effic / 100.0;
+ roundintby(lp->lnd_item[I_MILIT], 10));
+ estimate = lp->lnd_item[I_MILIT] * lp->lnd_effic / 100.0;
- if (chance((double)(spy + lp->lnd_vis) / 20.0)) {
+ if (chance((spy + lp->lnd_vis) / 20.0)) {
int t;
t = lp->lnd_tech - 20 + roll(40);
- t = max(t, 0);
+ t = MAX(t, 0);
if (destination == player->cnum)
pr(", tech %d)\n", t);
else
struct lndstr land;
snxtitem_all(&ni, EF_LAND);
- while (nxtitem(&ni, (s_char *)&land)) {
+ while (nxtitem(&ni, &land)) {
if (!land.lnd_own)
continue;
if (land.lnd_x != sp->sct_x || land.lnd_y != sp->sct_y)
return;
snxtitem_xy(&ni, EF_LAND, sp->shp_x, sp->shp_y);
- while (nxtitem(&ni, (s_char *)&land)) {
+ while (nxtitem(&ni, &land)) {
if (land.lnd_own == 0)
continue;
if (land.lnd_ship == sp->shp_uid)
return;
snxtitem_xy(&ni, EF_LAND, lp->lnd_x, lp->lnd_y);
- while (nxtitem(&ni, (s_char *)&land)) {
+ while (nxtitem(&ni, &land)) {
if (land.lnd_own == 0)
continue;
if (land.lnd_land == lp->lnd_uid)
struct llist *llp;
emp_initque(list);
- while (nxtitem(ni, (s_char *)&land)) {
+ while (nxtitem(ni, &land)) {
if (!player->owner)
continue;
if (opt_MARKET) {
- if (ontradingblock(EF_LAND, (int *)&land)) {
+ if (ontradingblock(EF_LAND, &land)) {
pr("unit #%d inelligible - it's for sale.\n",
land.lnd_uid);
continue;
land.lnd_harden = 0;
memset(land.lnd_rpath, 0, sizeof(land.lnd_rpath));
putland(land.lnd_uid, &land);
- llp = (struct llist *)malloc(sizeof(struct llist));
+ llp = malloc(sizeof(struct llist));
llp->lcp = lcp;
llp->land = land;
- llp->mobil = (double)land.lnd_mobil;
+ llp->mobil = land.lnd_mobil;
emp_insque(&llp->queue, list);
}
}
coord allx;
coord ally;
int first = 1;
- s_char mess[128];
+ char mess[128];
int rel;
*minmobp = 9876.0;
mpr(actor, "%s was disbanded at %s\n",
prland(&land), xyas(land.lnd_x, land.lnd_y, land.lnd_own));
emp_remque((struct emp_qelem *)llp);
- free((s_char *)llp);
+ free(llp);
continue;
}
if (land.lnd_ship >= 0) {
}
if (!(lchr[(int)llp->land.lnd_type].l_flags & L_SPY) &&
!(lchr[(int)llp->land.lnd_type].l_flags & L_TRAIN) &&
- lnd_getmil(&llp->land) == 0) {
+ llp->land.lnd_item[I_MILIT] == 0) {
lnd_mess("has no mil on it to guide it", llp);
continue;
}
if (land.lnd_x != allx || land.lnd_y != ally)
*togetherp = 0;
if (land.lnd_mobil + 1 < (int)llp->mobil) {
- llp->mobil = (double)land.lnd_mobil;
+ llp->mobil = land.lnd_mobil;
}
if (llp->mobil < *minmobp)
*minmobp = llp->mobil;
void
lnd_put(struct emp_qelem *list, natid actor)
{
- register struct emp_qelem *qp;
- register struct emp_qelem *newqp;
+ struct emp_qelem *qp;
+ struct emp_qelem *newqp;
struct llist *llp;
qp = list->q_back;
putland(llp->land.lnd_uid, &llp->land);
newqp = qp->q_back;
emp_remque(qp);
- free((s_char *)qp);
+ free(qp);
qp = newqp;
}
}
struct llist *llp;
struct sctstr sect;
int mines, m, max, sshells, lshells;
- double mobcost;
for (qp = land_list->q_back; qp != land_list; qp = next) {
next = qp->q_back;
continue;
}
if (takemob) {
-/* mobcost = llp->land.lnd_effic * 0.01 * llp->lcp->l_spd;*/
- mobcost = llp->land.lnd_spd;
- mobcost = 480.0 / (mobcost +
- techfact(llp->land.lnd_tech, mobcost));
- llp->mobil -= mobcost;
+ llp->mobil -= lnd_pathcost(&llp->land, 0.2);
llp->land.lnd_mobil = (int)llp->mobil;
llp->land.lnd_harden = 0;
}
putland(llp->land.lnd_uid, &llp->land);
if (!(mines = sect.sct_mines))
continue;
- max = vl_find(V_SHELL, llp->lcp->l_vtype,
- llp->lcp->l_vamt, (int)llp->lcp->l_nv);
+ max = llp->lcp->l_item[I_SHELL];
lshells = llp->land.lnd_item[I_SHELL];
sshells = sect.sct_item[I_SHELL];
for (m = 0; mines > 0 && m < max * 2; m++) {
lnd_hit_mine(&llp->land, llp->lcp);
sect.sct_mines--;
putsect(§);
- putland(llp->land.lnd_uid, (s_char *)&llp->land);
+ putland(llp->land.lnd_uid, &llp->land);
if (!llp->land.lnd_own) {
stopping = 1;
emp_remque(qp);
- free((s_char *)qp);
+ free(qp);
}
}
}
struct emp_qelem *next;
struct llist *llp;
struct lndstr *lnd;
- int vec[I_MAX + 1];
pr("lnd# land type x,y a eff sh gun xl mu tech retr fuel\n");
pr("%4d ", lnd->lnd_uid);
pr("%-16.16s ", llp->lcp->l_name);
prxy("%4d,%-4d ", lnd->lnd_x, lnd->lnd_y, llp->land.lnd_own);
- pr("%1c", lnd->lnd_army);
+ pr("%1.1s", &lnd->lnd_army);
pr("%4d%%", lnd->lnd_effic);
- getvec(VT_ITEM, vec, (s_char *)lnd, EF_LAND);
- pr("%4d", vec[I_SHELL]);
- pr("%4d", vec[I_GUN]);
+ pr("%4d", lnd->lnd_item[I_SHELL]);
+ pr("%4d", lnd->lnd_item[I_GUN]);
count_land_planes(lnd);
pr("%3d", lnd->lnd_nxlight);
pr("%4d", lnd->lnd_mobil);
}
}
-void
-lnd_mess(s_char *str, struct llist *llp)
+static void
+lnd_mess(char *str, struct llist *llp)
{
mpr(llp->land.lnd_own, "%s %s & stays in %s\n",
prland(&llp->land),
llp->land.lnd_mobil = llp->mobil;
putland(llp->land.lnd_uid, &llp->land);
emp_remque((struct emp_qelem *)llp);
- free((s_char *)llp);
+ free(llp);
}
static int
if (!totdam || !(count = lnd_count(list)))
return 0;
- dam = ldround(((double)totdam / (double)count), 1);
+ dam = ldround((double)totdam / count, 1);
for (qp = list->q_back; qp != list; qp = next) {
next = qp->q_back;
llp = (struct llist *)qp;
putland(llp->land.lnd_uid, &llp->land);
if (!llp->land.lnd_own) {
emp_remque(qp);
- free((s_char *)qp);
+ free(qp);
}
}
return dam;
{
struct nstr_sect ns;
struct sctstr fsect;
- int trange;
- double range, range2, guneff;
+ int trange, range;
+ double guneff;
int shell, gun;
int dam;
int totdam = 0;
continue;
if (fsect.sct_own == victim)
continue;
- if (fsect.sct_type != SCT_FORTR)
- continue;
if (getrel(getnatp(fsect.sct_own), victim) >= NEUTRAL)
continue;
gun = fsect.sct_item[I_GUN];
if (gun < 1)
continue;
- range = tfactfire(fsect.sct_own, (double)min(gun, 7));
- if (fsect.sct_effic > 59)
- range++;
- range2 = roundrange(range);
+ range = roundrange(fortrange(&fsect));
trange = mapdist(newx, newy, fsect.sct_x, fsect.sct_y);
- if (trange > range2)
+ if (trange > range)
continue;
if (fsect.sct_item[I_MILIT] < 5)
continue;
shell = fsect.sct_item[I_SHELL];
if (shell < 1)
- shell += supply_commod(fsect.sct_own,
- fsect.sct_x, fsect.sct_y, I_SHELL, 1);
+ shell += supply_commod(fsect.sct_own, fsect.sct_x, fsect.sct_y,
+ I_SHELL, 1);
if (shell < 1)
continue;
shell--;
struct sctstr sect;
getsect(lp->lnd_x, lp->lnd_y, §);
- return (int)(((double)lp->lnd_effic / 100.0) *
- (10 + dchr[sect.sct_type].d_dstr * 2 +
- (double)lp->lnd_spd / 2.0 - lp->lnd_vis));
+ return (int)((lp->lnd_effic / 100.0) *
+ (10 + dchr[sect.sct_type].d_dstr * 2 + lp->lnd_spd / 2.0
+ - lp->lnd_vis));
}
-int
+static int
lnd_hit_mine(struct lndstr *lp, struct lchrstr *lcp)
{
double m;
nreport(lp->lnd_own, N_LHIT_MINE, 0, 1);
- m = roll(20) + 10;
+ m = MINE_LDAMAGE();
if (lcp->l_flags & L_ENGINEER)
m /= 2.0;
}
double
-lnd_mobcost(struct lndstr *lp, struct sctstr *sp, int mobtype)
+lnd_pathcost(struct lndstr *lp, double pathcost)
{
- double mobcost;
- double smobcost;
+ double effspd;
- /* supply unit's speed depends on their eff, since
- that is their purpose */
+ effspd = lp->lnd_spd;
if (lchr[(int)lp->lnd_type].l_flags & L_SUPPLY)
- mobcost = lp->lnd_effic * 0.01 * lp->lnd_spd;
- else
- mobcost = lp->lnd_spd;
- if (mobcost < 0.01)
- mobcost = 0.01;
-
-/* sector_mcost now takes 2 different arguments, a sector pointer, and
- whether or not to figure in the highway bonus, rail bonus or none.
- bridge heads, bridges and highways have built-in highways bonus
- because they are a 1, and this will discount that. */
-
- smobcost = (double)sector_mcost(sp, mobtype);
- if (smobcost < 0.01)
- smobcost = 0.01;
-
-/* marching through 0 mobility conquered sectors takes lots of mobility,
- unless you are a train. Capturing railways is a good thing. */
-
- if (sp->sct_own != sp->sct_oldown && sp->sct_mobil <= 0 &&
- smobcost < LND_MINMOBCOST && mobtype != MOB_RAIL)
- smobcost = LND_MINMOBCOST;
+ effspd *= lp->lnd_effic * 0.01;
+
+ /*
+ * The return value must be PATHCOST times a factor that depends
+ * only on the land unit. Anything else breaks path finding. In
+ * particular, you can't add or enforce a minimum cost here. Do
+ * it in sector_mcost().
+ */
+ return pathcost * 5.0 * speed_factor(effspd, lp->lnd_tech);
+}
- mobcost = smobcost * 5.0 * 480.0 /
- (mobcost + techfact(lp->lnd_tech, mobcost));
+int
+lnd_mobtype(struct lndstr *lp)
+{
+ return (lchr[(int)lp->lnd_type].l_flags & L_TRAIN)
+ ? MOB_RAIL : MOB_MARCH;
+}
- return mobcost;
+double
+lnd_mobcost(struct lndstr *lp, struct sctstr *sp)
+{
+ return lnd_pathcost(lp, sector_mcost(sp, lnd_mobtype(lp)));
}
int
struct emp_qelem *qp2;
struct emp_qelem *next;
struct llist *llp;
+ struct emp_qelem cur, done;
coord dx;
coord dy;
coord newx;
coord newy;
int stopping = 0;
- int visible = 0;
+ int visible;
int stop;
- s_char dp[80];
+ char dp[80];
int rel;
int oldown;
continue;
}
}
-
- if (!(lchr[(int)llp->land.lnd_type].l_flags & L_SPY))
- visible = 1;
if (sect.sct_rail == 0 &&
lchr[(int)llp->land.lnd_type].l_flags & L_TRAIN) {
if (together) {
}
/* Note we check would_abandon first because we don't want
to always have to do these checks */
- if (would_abandon(&osect, V_CIVIL, 0, &(llp->land))) {
+ if (would_abandon(&osect, I_CIVIL, 0, &llp->land)) {
stop = 0;
- if (!want_to_abandon(&osect, V_CIVIL, 0, &(llp->land))) {
+ if (!want_to_abandon(&osect, I_CIVIL, 0, &llp->land)) {
stop = 1;
}
/* now check stuff */
if (!check_sect_ok(&osect))
return 1;
for (qp2 = list->q_back; qp2 != list; qp2 = qp2->q_back) {
- if (!check_land_ok(&(((struct llist *)qp2)->land)))
+ if (!check_land_ok(&((struct llist *)qp2)->land))
return 1;
}
if (stop) {
}
llp->land.lnd_x = newx;
llp->land.lnd_y = newy;
- if (lchr[(int)llp->land.lnd_type].l_flags & L_TRAIN) {
- llp->mobil -= lnd_mobcost(&llp->land, §, MOB_RAIL);
- } else {
- llp->mobil -= lnd_mobcost(&llp->land, §, MOB_ROAD);
- }
+ llp->mobil -= lnd_mobcost(&llp->land, §);
llp->land.lnd_mobil = (int)llp->mobil;
llp->land.lnd_harden = 0;
putland(llp->land.lnd_uid, &llp->land);
stopping |= lnd_check_mines(list);
if (QEMPTY(list))
return stopping;
- if (visible)
- stopping |= lnd_interdict(list, newx, newy, actor);
+
+ /* interdict land units sector by sector */
+ emp_initque(&cur);
+ emp_initque(&done);
+ while (!QEMPTY(list)) {
+ llp = (struct llist *)list->q_back;
+ newx = llp->land.lnd_x;
+ newy = llp->land.lnd_y;
+ /* move units in NEWX,NEWY to cur */
+ visible = 0;
+ for (qp = list->q_back; qp != list; qp = next) {
+ next = qp->q_back;
+ llp = (struct llist *)qp;
+ if (llp->land.lnd_x == newx && llp->land.lnd_y == newy) {
+ emp_remque(qp);
+ emp_insque(qp, &cur);
+ if (!(lchr[(int)llp->land.lnd_type].l_flags & L_SPY))
+ visible = 1;
+ }
+ }
+ /* interdict them */
+ if (visible)
+ stopping |= lnd_interdict(&cur, newx, newy, actor);
+ /* move survivors to done */
+ for (qp = cur.q_back; qp != &cur; qp = next) {
+ next = qp->q_back;
+ llp = (struct llist *)qp;
+ emp_remque(qp);
+ emp_insque(qp, &done);
+ }
+ }
+ /* assign surviving land units back to list */
+ emp_insque(list, &done);
+ emp_remque(&done);
+
return stopping;
}
* find all artillery units belonging
* to the attacker or defender that can fire.
* Each arty unit adds +1%/damage point
- *
*/
int
-lnd_support(natid victim, natid attacker, coord x, coord y)
+lnd_support(natid victim, natid attacker, coord x, coord y, int defending)
{
struct nstr_item ni;
struct lndstr land;
int dist;
int shell;
int gun;
- double range, range2;
+ int range;
snxtitem_all(&ni, EF_LAND);
- while (nxtitem(&ni, (s_char *)&land)) {
+ while (nxtitem(&ni, &land)) {
if (land.lnd_frg == 0)
continue;
if ((land.lnd_x == x) && (land.lnd_y == y))
continue;
if (land.lnd_land >= 0)
continue;
- if (land.lnd_mission > 0)
- continue;
if (land.lnd_effic < LAND_MINFIREEFF)
continue;
/* Do we have mil? */
/* are we in range? */
dist = mapdist(land.lnd_x, land.lnd_y, x, y);
- range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
-
- range2 = roundrange(range);
- if (dist > range2)
+ range = roundrange(effrange(land.lnd_frg, land.lnd_tech));
+ if (dist > range)
continue;
shell = land.lnd_item[I_SHELL];
continue;
use_supply(&land);
- nreport(land.lnd_own, N_FIRE_L_ATTACK, victim, 1);
+ if (defending)
+ nreport(land.lnd_own, N_FIRE_BACK, victim, 1);
+ else
+ nreport(land.lnd_own, N_FIRE_L_ATTACK, victim, 1);
if (roll(100) < land.lnd_acc) {
dam += landunitgun(land.lnd_effic, land.lnd_dam, gun,
land.lnd_ammo, shell) / 2;
return (int)dam;
}
-s_char *
-lnd_path(int together, struct lndstr *lp, s_char *buf)
+char *
+lnd_path(int together, struct lndstr *lp, char *buf)
{
coord destx;
coord desty;
struct sctstr d_sect, sect;
- s_char *cp;
+ char *cp;
double dummy;
+ int mtype;
if (!sarg_xy(buf, &destx, &desty))
return 0;
return 0;
}
getsect(lp->lnd_x, lp->lnd_y, §);
- if (lchr[(int)lp->lnd_type].l_flags & L_TRAIN)
- cp = (s_char *)BestLandPath(buf, §, &d_sect, &dummy, MOB_RAIL);
- else
- cp = (s_char *)BestLandPath(buf, §, &d_sect, &dummy, MOB_ROAD);
+ mtype = lnd_mobtype(lp);
+ cp = BestLandPath(buf, §, &d_sect, &dummy, mtype);
if (!cp) {
- pr("No owned path from %s to %s!\n",
+ pr("No owned %s from %s to %s!\n",
+ mtype == MOB_RAIL ? "railway" : "path",
xyas(lp->lnd_x, lp->lnd_y, player->cnum),
xyas(d_sect.sct_x, d_sect.sct_y, player->cnum));
return 0;
{
struct lchrstr *lcp = &lchr[(int)lp->lnd_type];
-/* if (lcp->l_flags & L_SUPPLY ||
- lcp->l_flags & L_SECURITY ||
- lcp->l_flags & L_FLAK ||
- lcp->l_frg)
- return 0; */
if (lcp->l_flags & L_SUPPLY)
return 0;
if ((lp->lnd_ship >= 0) || lp->lnd_land >= 0)
return 0;
- hard_amt = min(lp->lnd_mobil, hard_amt);
+ hard_amt = MIN(lp->lnd_mobil, hard_amt);
if ((lp->lnd_harden + hard_amt) > land_mob_max)
hard_amt = land_mob_max - lp->lnd_harden;
eng = has_helpful_engineer(lp->lnd_x, lp->lnd_y, lp->lnd_own);
if (eng)
- hard_amt = ((float)hard_amt * 1.5);
+ hard_amt *= 1.5;
if ((lp->lnd_harden + hard_amt) > land_mob_max)
hard_amt = land_mob_max - lp->lnd_harden;
/* Now, if an engineer helped, it's really only 2/3rds of
that */
if (eng)
- mob_used = (int)((float)mob_used / 1.5);
+ mob_used /= 1.5;
/* If we increased it, but not much, we gotta take at least 1
mob point. */
lp->lnd_mobil = 0;
lp->lnd_harden += hard_amt;
- lp->lnd_harden = min(lp->lnd_harden, land_mob_max);
+ lp->lnd_harden = MIN(lp->lnd_harden, land_mob_max);
return hard_amt;
}
+
+/*
+ * Set LP's tech to TLEV along with everything else that depends on it.
+ */
+void
+lnd_set_tech(struct lndstr *lp, int tlev)
+{
+ struct lchrstr *lcp = lchr + lp->lnd_type;
+ int tech_diff = tlev - lcp->l_tech;
+
+ if (CANT_HAPPEN(tech_diff < 0)) {
+ tlev -= tech_diff;
+ tech_diff = 0;
+ }
+
+ lp->lnd_tech = tlev;
+ lp->lnd_att = (float)LND_ATTDEF(lcp->l_att, tech_diff);
+ lp->lnd_def = (float)LND_ATTDEF(lcp->l_def, tech_diff);
+ lp->lnd_vul = (int)LND_VUL(lcp->l_vul, tech_diff);
+ lp->lnd_spd = (int)LND_SPD(lcp->l_spd, tech_diff);
+ lp->lnd_vis = (int)LND_VIS(lcp->l_vis, tech_diff);
+ lp->lnd_spy = (int)LND_SPY(lcp->l_spy, tech_diff);
+ lp->lnd_rad = (int)LND_RAD(lcp->l_rad, tech_diff);
+ lp->lnd_frg = (int)LND_FRG(lcp->l_frg, tech_diff);
+ lp->lnd_acc = (int)LND_ACC(lcp->l_acc, tech_diff);
+ lp->lnd_dam = (int)LND_DAM(lcp->l_dam, tech_diff);
+ lp->lnd_ammo = (int)LND_AMM(lcp->l_ammo, lcp->l_dam, tech_diff);
+ lp->lnd_aaf = (int)LND_AAF(lcp->l_aaf, tech_diff);
+ lp->lnd_fuelc = (int)LND_FC(lcp->l_fuelc, tech_diff);
+ lp->lnd_fuelu = (int)LND_FU(lcp->l_fuelu, tech_diff);
+ lp->lnd_maxlight = (int)LND_XPL(lcp->l_nxlight, tech_diff);
+ lp->lnd_maxland = (int)LND_MXL(lcp->l_nland, tech_diff);
+}