]> git.pond.sub.org Git - empserver/blobdiff - src/lib/commands/boar.c
Update copyright notice
[empserver] / src / lib / commands / boar.c
index 4352cc02c0a68673b91f26a85e46262d8c67c8e6..8edf5d9dcf7e18ad5fea4f44a89ee2b04dc8f638 100644 (file)
@@ -1,11 +1,11 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
- *                           Ken Stevens, Steve McClure
+ *  Copyright (C) 1986-2020, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *                Ken Stevens, Steve McClure, Markus Armbruster
  *
- *  This program is free software; you can redistribute it and/or modify
+ *  Empire is free software: you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
+ *  the Free Software Foundation, either version 3 of the License, or
  *  (at your option) any later version.
  *
  *  This program is distributed in the hope that it will be useful,
  *  GNU General Public License for more details.
  *
  *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
  *
  *  ---
  *
- *  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.
  *
  *  ---
  *
  *  boar.c: Board an enemy ship
- * 
+ *
  *  Known contributors to this file:
  *     Ken Stevens, 1995
+ *     Markus Armbruster, 2011-2015
  */
 
-#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 "nsc.h"
-#include "mission.h"
-#include "ship.h"
+#include <config.h>
+
 #include "combat.h"
-#include "retreat.h"
 #include "commands.h"
+#include "land.h"
+#include "retreat.h"
+#include "ship.h"
 
 int
 boar(void)
 {
-       struct  combat off[1];  /* boarding ship or sector */
-       struct  combat def[1];  /* defending ship */
-       struct  emp_qelem olist;        /* boarding units */
-       struct  emp_qelem dlist;        /* defending units */
-       int     ototal;         /* total boarding strength */
-       int     a_engineer = 0; /* boarder engineers are present */
-       int     a_spy = 0;      /* the best boarder scout */
-       struct  shpstr  ship;   /* for retreating */
-       struct  sctstr  sect;
-       struct  lndstr  land;
-       struct  nstr_item ni;
-       int     foundland;
-       s_char  *p;
-       s_char  buf[1024];
-
-       att_combat_init(def, EF_SHIP);
-       /*
-        * Collect input from the boarder
-        */
-
-       /* What are we boarding? */
-
-       if (!(p = getstarg(player->argp[1], "Victim ship #?  ", buf)) ||
-           (def->shp_uid = atoi(p)) < 0)
-               return RET_SYN;
-
-       /*
-        * Ask the boarder what he wants to board with
-        */
-
-       if (!(p = getstarg(player->argp[2], "Boarding party from? ", buf)))
-               return RET_SYN;
-       if (issector(p)) {
-               att_combat_init(off, EF_SECTOR);
-               if (!sarg_xy(p, &off->x, &off->y))
-                       return RET_SYN;
-                getsect(off->x, off->y, &sect);
-                if (sect.sct_own != player->cnum) {
-                   pr("You don't own %s!\n",
-                      xyas(off->x, off->y, player->cnum));
-                   return RET_SYN;
-                }
-               if (sect.sct_mobil <= 0) {
-                   /* Look for land units with mobility */
-                   snxtitem_xy(&ni, EF_LAND, off->x, off->y);
-                   foundland = 0;
-                   while (nxtitem(&ni, (s_char *)&land)) {
-                       if (land.lnd_own != player->cnum)
-                           continue;
-                       if (land.lnd_ship >= 0)
-                           continue;
-                       if (land.lnd_mobil <= 0)
-                           continue;
-                       /* Only land units with assault can board */
-                       if (!(lchr[(int)land.lnd_type].l_flags & L_ASSAULT))
-                           continue;
-                       foundland = 1;
-                   }
-                   if (!foundland) {
-                       pr("You don't have any mobility (sector or land units) in %s!\n",
-                          xyas(off->x, off->y, player->cnum));
-                       return RET_SYN;
-                   }
-               }
-       } else {
-               att_combat_init(off, EF_SHIP);
-               if ((off->shp_uid = atoi(p)) < 0)
-                       return RET_SYN;
-       }
-       if (att_abort(A_BOARD, off, def)) {
-               pr("Board aborted\n");
-               return RET_OK;
-       }
-
-       /* Fire at the attacking ship */
-
-       att_approach(off, def);
-       if (att_abort(A_BOARD, off, def)) {
-               pr("Board aborted\n");
-               att_empty_attack(A_BOARD, 0, def);
-               return RET_OK;
-       }
-
-       /* Show what we're boarding, and check treaties */
-
-       if (att_show(def))
-           return RET_FAIL;
-
-       /* Ask the player what he wants to board with */
-
-       att_ask_offense(A_BOARD, off, def, &olist, &a_spy, &a_engineer);
-       if (att_abort(A_BOARD, off, def)) {
-               pr("Board aborted\n");
-               att_empty_attack(A_BOARD, 0, def);
-               return att_free_lists(&olist, 0);
+    struct combat off[1];      /* boarding ship or sector */
+    struct combat def[1];      /* defending ship */
+    struct emp_qelem olist;    /* boarding units */
+    struct emp_qelem dlist;    /* defending units */
+    int ototal;                        /* total boarding strength */
+    int a_engineer = 0;                /* boarder engineers are present */
+    int a_spy = 0;             /* the best boarder scout */
+    struct shpstr ship;                /* for retreating */
+    struct sctstr sect;
+    struct lndstr land;
+    struct nstr_item ni;
+    int foundland, def_uid;
+    natid def_own;
+    char *p;
+    char buf[1024];
+
+    att_combat_init(def, EF_SHIP);
+    /*
+     * Collect input from the boarder
+     */
+
+    /* What are we boarding? */
+    p = getstarg(player->argp[1], "Victim ship #?  ", buf);
+    if (!p || (def->shp_uid = atoi(p)) < 0)
+       return RET_SYN;
+
+    /*
+     * Ask the boarder what he wants to board with
+     */
+
+    if (!(p = getstarg(player->argp[2], "Boarding party from? ", buf)))
+       return RET_SYN;
+    if (issector(p)) {
+       att_combat_init(off, EF_SECTOR);
+       if (!sarg_xy(p, &off->x, &off->y))
+           return RET_SYN;
+       getsect(off->x, off->y, &sect);
+       if (sect.sct_own != player->cnum) {
+           pr("You don't own %s!\n", xyas(off->x, off->y, player->cnum));
+           return RET_SYN;
        }
-
-       /*
-        * Estimate the defense strength and give the player a chance to abort
-        */
-
-       ototal = att_estimate_defense(A_BOARD, off, &olist, def, a_spy);
-       if (att_abort(A_BOARD, off, def)) {
-               pr("Board aborted\n");
-               att_empty_attack(A_BOARD, 0, def);
-               return att_free_lists(&olist, 0);
+       if (sect.sct_mobil <= 0) {
+           /* Look for land units with mobility */
+           snxtitem_xy(&ni, EF_LAND, off->x, off->y);
+           foundland = 0;
+           while (nxtitem(&ni, &land)) {
+               if (land.lnd_own != player->cnum)
+                   continue;
+               if (land.lnd_ship >= 0 || land.lnd_land >= 0)
+                   continue;
+               if (land.lnd_mobil <= 0)
+                   continue;
+               /* Only land units with assault can board */
+               if (!(lchr[(int)land.lnd_type].l_flags & L_ASSAULT))
+                   continue;
+               foundland = 1;
+           }
+           if (!foundland) {
+               pr("You don't have any mobility (sector or land units) in %s!\n",
+                  xyas(off->x, off->y, player->cnum));
+               return RET_SYN;
+           }
        }
+    } else {
+       att_combat_init(off, EF_SHIP);
+       if ((off->shp_uid = atoi(p)) < 0)
+           return RET_SYN;
+    }
+    if (att_abort(A_BOARD, off, def)) {
+       pr("Board aborted\n");
+       return RET_OK;
+    }
 
-       /*
-        * We have now got all the answers from the boarder.  From this point
-        * forward, we can assume that this battle is the _only_ thing
-        * happening in the game.
-        */
-
-       /* Get the real defense */
-
-       att_get_defense(&olist, def, &dlist, a_spy, ototal);
-
-       /*
-        * Death, carnage, and destruction.
-        */
+    /* Fire at the attacking ship */
 
-       if (!(att_fight(A_BOARD,off,&olist,1.0,def,&dlist,1.0))) {
-               getship(def->shp_uid, &ship);
-               if (ship.shp_rflags & RET_BOARDED) {
-                       retreat_ship(&ship, 'u');
-                       putship(def->shp_uid, &ship);
-               }
+    att_approach(off, def);
+    if (att_abort(A_BOARD, off, def)) {
+       pr("Board aborted\n");
+       att_empty_attack(A_BOARD, 0, def);
+       return RET_OK;
+    }
+
+    /* Show what we're boarding */
+    att_show(def);
+
+    /* Ask the player what he wants to board with */
+
+    att_ask_offense(A_BOARD, off, def, &olist, &a_spy, &a_engineer);
+    if (att_abort(A_BOARD, off, def)) {
+       pr("Board aborted\n");
+       att_empty_attack(A_BOARD, 0, def);
+       return att_free_lists(&olist, NULL);
+    }
+
+    ototal = att_get_offense(A_BOARD, off, &olist, def);
+    if (att_abort(A_BOARD, off, def)) {
+       pr("Board aborted\n");
+       att_empty_attack(A_BOARD, 0, def);
+       return att_free_lists(&olist, NULL);
+    }
+
+    /*
+     * We have now got all the answers from the boarder.  From this point
+     * forward, we can assume that this battle is the _only_ thing
+     * happening in the game.
+     */
+
+    /* Get the real defense */
+
+    att_get_defense(&olist, def, &dlist, a_spy, ototal);
+
+    /*
+     * Death, carnage, and destruction.
+     */
+
+    /*
+     * Careful: when the fight sinks the ship, put_combat() clobbers
+     * *def (see FIXME there).
+     */
+    def_uid = def->shp_uid;
+    def_own = def->own;
+    if (!(att_fight(A_BOARD, off, &olist, 1.0, def, &dlist, 1.0))) {
+       getship(def_uid, &ship);
+       if (ship.shp_rflags & RET_BOARDED) {
+           retreat_ship(&ship, def_own, 'u');
+           putship(def_uid, &ship);
        }
+    }
 
-       return RET_OK;
+    return RET_OK;
 }