/*
* Empire - A multi-player, client/server Internet based war game.
- * Copyright (C) 1986-2015, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ * Copyright (C) 1986-2017, Dave Pare, Jeff Bailey, Thomas Ruschak,
* Ken Stevens, Steve McClure, Markus Armbruster
*
* Empire is free software: you can redistribute it and/or modify
#include <config.h>
#include <math.h>
-#include "file.h"
#include "map.h"
#include "optlist.h"
#include "path.h"
}
}
-static char *
-unit_path(struct empobj *unit, char *buf, size_t bufsz)
-{
- coord destx;
- coord desty;
- struct sctstr sect;
- size_t len;
- double c;
- int mtype;
-
- if (CANT_HAPPEN(unit->ef_type != EF_LAND && unit->ef_type != EF_SHIP))
- return NULL;
-
- if (!sarg_xy(buf, &destx, &desty))
- return buf;
- if (unit->ef_type == EF_SHIP) {
- c = path_find(unit->x, unit->y, destx, desty,
- player->cnum, MOB_SAIL);
- if (c < 0 || unit->mobil <= 0) {
- pr("Can't get to '%s' right now.\n",
- xyas(destx, desty, player->cnum));
- return NULL;
- }
- } else {
- getsect(unit->x, unit->y, §);
- mtype = lnd_mobtype((struct lndstr *)unit);
- /*
- * Note: passing sect.sct_own for actor is funny, but works:
- * its only effect is to confine the search to that nation's
- * land. It doesn't affect mobility costs. The real actor is
- * different for marching in allied land, and passing it would
- * break path finding there.
- */
- c = path_find(unit->x, unit->y, destx, desty, sect.sct_own, mtype);
- if (c < 0) {
- pr("No owned %s from %s to %s!\n",
- mtype == MOB_RAIL ? "railway" : "path",
- xyas(unit->x, unit->y, player->cnum),
- xyas(destx, desty, player->cnum));
- return NULL;
- }
- }
- len = path_find_route(buf, bufsz, unit->x, unit->y, destx, desty);
- if (len == 0 || unit->ef_type == EF_LAND) {
- if (len + 1 < bufsz)
- strcpy(buf + len, "h");
- len++;
- }
- if (len >= bufsz) {
- pr("Can't handle path to %s, it's too long, sorry\n",
- xyas(destx, desty, player->cnum));
- return NULL;
- }
- pr("Using path '%s'\n", buf);
- return buf;
-}
-
static void
unit_view(struct emp_qelem *list)
{
return getstring(prompt, path);
}
+static char *
+unit_move_route(struct empobj *unit, char *buf, size_t bufsz)
+{
+ coord destx;
+ coord desty;
+ struct sctstr sect;
+ size_t len;
+ double c;
+ int mtype;
+
+ if (CANT_HAPPEN(unit->ef_type != EF_LAND && unit->ef_type != EF_SHIP))
+ return NULL;
+
+ if (!sarg_xy(buf, &destx, &desty))
+ return buf;
+ if (unit->ef_type == EF_SHIP) {
+ c = path_find(unit->x, unit->y, destx, desty,
+ player->cnum, MOB_SAIL);
+ if (c < 0 || unit->mobil <= 0) {
+ pr("Can't get to '%s' right now.\n",
+ xyas(destx, desty, player->cnum));
+ return NULL;
+ }
+ } else {
+ getsect(unit->x, unit->y, §);
+ mtype = lnd_mobtype((struct lndstr *)unit);
+ /*
+ * Note: passing sect.sct_own for actor is funny, but works:
+ * its only effect is to confine the search to that nation's
+ * land. It doesn't affect mobility costs. The real actor is
+ * different for marching in allied land, and passing it would
+ * break path finding there.
+ */
+ c = path_find(unit->x, unit->y, destx, desty, sect.sct_own, mtype);
+ if (c < 0) {
+ pr("No owned %s from %s to %s!\n",
+ mtype == MOB_RAIL ? "railway" : "path",
+ xyas(unit->x, unit->y, player->cnum),
+ xyas(destx, desty, player->cnum));
+ return NULL;
+ }
+ }
+ len = path_find_route(buf, bufsz, unit->x, unit->y, destx, desty);
+ if (len == 0 || unit->ef_type == EF_LAND) {
+ if (len + 1 < bufsz)
+ strcpy(buf + len, "h");
+ len++;
+ }
+ if (len >= bufsz) {
+ pr("Can't handle path to %s, it's too long, sorry\n",
+ xyas(destx, desty, player->cnum));
+ return NULL;
+ }
+ pr("Using path '%s'\n", buf);
+ return buf;
+}
+
int
unit_move(struct emp_qelem *list)
{
cp = "";
if (player->argp[2]) {
strcpy(path, player->argp[2]);
- cp = unit_path(leader, path, sizeof(path));
+ cp = unit_move_route(leader, path, sizeof(path));
if (!cp)
cp = "";
}
*/
if (!*cp) {
cp = unit_move_getpath(list, suppress_map, path);
- if (!cp)
+ if (!cp) {
+ if (type == EF_SHIP) {
+ shp_nav_stay_behind(list, player->cnum);
+ shp_nav_put(list, player->cnum);
+ } else {
+ lnd_mar_stay_behind(list, player->cnum);
+ lnd_mar_put(list, player->cnum);
+ }
return RET_FAIL;
- cp = unit_path(leader, path, sizeof(path));
+ }
+ cp = unit_move_route(leader, path, sizeof(path));
if (!cp || !*cp)
cp = "h";
suppress_map = 0;
} else if ((dir = chkdir(*cp, DIR_STOP, DIR_LAST)) >= 0) {
cp++;
if (type == EF_SHIP)
- stopping = shp_nav_one_sector(list, dir, player->cnum);
+ stopping = shp_nav_dir(list, dir, player->cnum)
+ || shp_nav_gauntlet(list, 1, player->cnum);
else {
- if (!moved && !lnd_abandon_askyn(list))
+ if (!moved && !lnd_abandon_askyn(list)) {
+ lnd_mar_put(list, player->cnum);
return RET_FAIL;
- stopping = lnd_mar_one_sector(list, dir, player->cnum);
+ }
+ stopping = lnd_mar_dir(list, dir, player->cnum)
+ || lnd_mar_gauntlet(list, 1, player->cnum);
}
- if (dir == DIR_STOP)
+ if (dir == DIR_STOP) {
+ CANT_HAPPEN(!QEMPTY(list));
return RET_OK;
+ }
moved = 1;
if (stopping)
cp = "";
}
if (type == EF_SHIP)
- shp_nav(list, player->cnum);
+ shp_nav_stay_behind(list, player->cnum);
else
- lnd_mar(list, player->cnum);
+ lnd_mar_stay_behind(list, player->cnum);
if (QEMPTY(list)) {
pr("No %s left\n", type == EF_SHIP ? "ships" : "lands");
}
/*
- * Teleport UNIT to X,Y.
- * If UNIT's mission op-area is centered on it, keep it centered.
+ * Teleport @unit to @x,@y.
+ * If @unit's mission op-area is centered on it, keep it centered.
*/
void
unit_teleport(struct empobj *unit, coord x, coord y)
}
/*
- * Update cargo of CARRIER for movement or destruction.
+ * Update cargo of @carrier for movement or destruction.
* If the carrier is destroyed, destroy its cargo (planes, land units,
* nukes).
* Else update their location to the carrier's. Any op sectors equal
}
/*
- * Drop cargo of UNIT.
- * Give it to NEWOWN, unless it's zero.
+ * Drop cargo of @unit.
+ * Give it to @newown, unless it's zero.
*/
void
unit_drop_cargo(struct empobj *unit, natid newown)
}
/*
- * Give UNIT and its cargo to RECIPIENT.
- * No action if RECIPIENT already owns UNIT.
- * If GIVER is non-zero, inform RECIPIENT and GIVER of the transaction.
+ * Give @unit and its cargo to @recipient.
+ * No action if @recipient already owns @unit.
+ * If @giver is non-zero, inform @recipient and @giver of the transaction.
* Clears mission and group on the units given away.
*/
void
}
/*
- * Wipe orders and such from UNIT.
+ * Wipe orders and such from @unit.
*/
void
unit_wipe_orders(struct empobj *unit)