]> git.pond.sub.org Git - empserver/blobdiff - src/lib/subs/mslsub.c
Update copyright notice
[empserver] / src / lib / subs / mslsub.c
index 8834b661349e9ce31740308f08e24b49e52de012..f5decdd09a177b2087a184687b335d3272c2e458 100644 (file)
@@ -1,6 +1,6 @@
 /*
  *  Empire - A multi-player, client/server Internet based war game.
- *  Copyright (C) 1986-2004, Dave Pare, Jeff Bailey, Thomas Ruschak,
+ *  Copyright (C) 1986-2009, 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.
  *
  *  ---
  *
  *  mslsub.c: Missile subroutine stuff
- * 
+ *
  *  Known contributors to this file:
  *     Ken Stevens, 1995
  *     Steve McClure, 1996-2000
  */
 
-#include "misc.h"
-#include "queue.h"
-#include "player.h"
-#include "sect.h"
-#include "ship.h"
-#include "optlist.h"
-#include "nuke.h"
-#include "plane.h"
+#include <config.h>
+
+#include <stdlib.h>
+#include "file.h"
 #include "land.h"
+#include "misc.h"
+#include "mission.h"
+#include "nat.h"
 #include "news.h"
-#include "item.h"
-#include "xy.h"
 #include "nsc.h"
-#include "file.h"
-#include "nat.h"
+#include "nuke.h"
+#include "optlist.h"
 #include "path.h"
-#include "mission.h"
+#include "plane.h"
+#include "player.h"
 #include "prototypes.h"
+#include "queue.h"
+#include "sect.h"
+#include "ship.h"
+#include "xy.h"
 
 int
-msl_equip(struct plnstr *pp)
+msl_equip(struct plnstr *pp, char mission)
 {
     struct plist pl;
 
     memset(&pl, 0, sizeof(struct plist));
     pl.pcp = plchr + pp->pln_type;
     pl.plane = *pp;
-    return mission_pln_equip(&pl, 0, 0, 'p');
+    return mission_pln_equip(&pl, 0, 0, mission);
 }
 
 int
 msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
-       int snews_item, s_char *what, coord x, coord y, int victim)
+       int snews_item, char *what, coord x, coord y, int victim)
 {
     int hit;
     struct shpstr ship;
@@ -72,7 +74,7 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
     int sublaunch = 0;
     struct plchrstr *pcp = plchr + pp->pln_type;
     int hitchance = pln_hitchance(pp, hardtarget, type);
-    s_char *from;
+    char *from;
     int dam, dummyi;
 
     mpr(pp->pln_own, "Preparing to launch %s at %s %s %s%s\n",
@@ -105,33 +107,33 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
               * (1 - techfact(pp->pln_tech, 1.0)))) {
        mpr(pp->pln_own, "KABOOOOM!  Missile explodes %s!\n", from);
        if (chance(0.33)) {
-           if (pp->pln_nuketype != (s_char)-1 && opt_NUKEFAILDETONATE) {
-               pp->pln_flags &= ~PLN_AIRBURST;
-               detonate(pp, pp->pln_x, pp->pln_y);
-           } else {
-               dam = pln_damage(pp, pp->pln_x, pp->pln_y,
-                                'p', &dummyi, 1) / 2;
-               if (dam) {
-                   if (pp->pln_ship >= 0) {
-                       shipdamage(&ship, dam);
-                       putship(ship.shp_uid, &ship);
-                   } else {
-                       pr("Explosion damages %s %d%%",
-                          xyas(pp->pln_x, pp->pln_y, pp->pln_own), dam);
-                       getsect(pp->pln_x, pp->pln_y, &sect);
-                       sectdamage(&sect, dam, 0);
-                       putsect(&sect);
-                   }
+           dam = pln_damage(pp, pp->pln_x, pp->pln_y,
+                            'p', &dummyi, 1) / 2;
+           if (dam) {
+               if (pp->pln_ship >= 0) {
+                   shipdamage(&ship, dam);
+                   putship(ship.shp_uid, &ship);
+               } else {
+                   pr("Explosion damages %s %d%%",
+                      xyas(pp->pln_x, pp->pln_y, pp->pln_own), dam);
+                   getsect(pp->pln_x, pp->pln_y, &sect);
+                   sectdamage(&sect, dam);
+                   putsect(&sect);
                }
            }
        }
        return 0;
     }
 
+    CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED);
+    pp->pln_flags |= PLN_LAUNCHED;
+    putplane(pp->pln_uid, pp);
     mpr(pp->pln_own, "\tSHWOOOOOSH!  Missile launched!\n");
 
-    if (pp->pln_nuketype != (s_char)-1)
+    if (nuk_on_plane(pp) >= 0) {
        mpr(pp->pln_own, "\tArming nuclear warheads...\n");
+       hitchance = 100;
+    }
 
     if (pcp->pl_flags & P_T)
        mpr(victim, "Incoming %s missile sighted at %s...\n",
@@ -151,16 +153,13 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, int news_item,
        }
     }
 
-    if (pp->pln_nuketype != (s_char)-1)
-       hitchance = 100;
-
     mpr(pp->pln_own, "\t%d%% hitchance...", hitchance);
     hit = (roll(100) <= hitchance);
 
     mpr(pp->pln_own, hit ? "HIT!\n" : "miss\n");
     if (pcp->pl_flags & P_T)
        mpr(victim, "...Incoming %s missile %s\n",
-           sublaunch ? (s_char *)"" : cname(pp->pln_own),
+           sublaunch ? "" : cname(pp->pln_own),
            hit ? "HIT!\n" : "missed\n");
     if (hit && news_item) {
        if (sublaunch)
@@ -182,7 +181,7 @@ msl_sel(struct emp_qelem *list, coord x, coord y, natid victim,
 
     emp_initque(list);
     snxtitem_all(&ni, EF_PLANE);
-    while (nxtitem(&ni, (s_char *)&plane)) {
+    while (nxtitem(&ni, &plane)) {
        if (!plane.pln_own)
            continue;
 
@@ -195,18 +194,22 @@ msl_sel(struct emp_qelem *list, coord x, coord y, natid victim,
            continue;
        if (mission && plane.pln_mission != mission)
            continue;
+       if (mission &&
+           plane.pln_radius < mapdist(x, y, plane.pln_opx, plane.pln_opy))
+           continue;
        if (getrel(getnatp(plane.pln_own), victim) >= NEUTRAL)
            continue;
        /* missiles go one way, so we can use all the range */
        if (plane.pln_range < mapdist(x, y, plane.pln_x, plane.pln_y))
            continue;
-       if (plane.pln_mobil <= (s_char)0)
+       if (plane.pln_mobil <= 0)
            continue;
        if (plane.pln_effic < 100)
            continue;
+       if (!pln_airbase_ok(&plane, 1, 0))
+           continue;
        /* got a valid interceptor */
-       irv = (struct plist *)malloc(sizeof(*irv));
-       irv->state = P_OK;
+       irv = malloc(sizeof(*irv));
        irv->bombs = 0;
        irv->misc = 0;
        irv->pcp = &plchr[(int)plane.pln_type];
@@ -231,23 +234,19 @@ msl_intercept(coord x, coord y, natid bombown, int hardtarget,
     struct plist *ip;
     int icount = 0;
     short destroyed = 0;
-    s_char *att_name;
-    s_char *def_name;
+    char *att_name;
+    char *def_name;
     int news_item;
-    s_char *who = sublaunch ? (s_char *)"" : cname(bombown);
+    char *who = sublaunch ? "" : cname(bombown);
 
     getsect(x, y, &sect);
     if (wantflags == P_O && !nowantflags) {
        att_name = "satellite";
        def_name = "a-sat missile";
        news_item = N_SAT_KILL;
-       if (sect.sct_own) {
-           mpr(sect.sct_own, "%s has positioned a satellite over %s\n",
-               sublaunch ? (s_char *)"someone" : cname(bombown), xyas(x,
-                                                                      y,
-                                                                      sect.
-                                                                      sct_own));
-       }
+       mpr(sect.sct_own, "%s has positioned a satellite over %s\n",
+           sublaunch ? "someone" : cname(bombown),
+           xyas(x, y, sect.sct_own));
     } else if (wantflags == P_N && nowantflags == P_O) {
        att_name = "warhead";
        def_name = "abm";
@@ -274,7 +273,7 @@ msl_intercept(coord x, coord y, natid bombown, int hardtarget,
        pcp = ip->pcp;
        if (mission_pln_equip(ip, 0, 0, 'i') < 0) {
            emp_remque(qp);
-           free((s_char *)qp);
+           free(qp);
            continue;
        }
        /* got one interceptor, delete from irv_list and
@@ -293,7 +292,7 @@ msl_intercept(coord x, coord y, natid bombown, int hardtarget,
        pcp = ip->pcp;
        if (mission_pln_equip(ip, 0, 0, 'i') < 0) {
            emp_remque(qp);
-           free((s_char *)qp);
+           free(qp);
            continue;
        }
        /* got one interceptor, delete from irv_list and
@@ -308,12 +307,11 @@ msl_intercept(coord x, coord y, natid bombown, int hardtarget,
     while (!QEMPTY(irvlist)) {
        qp = irvlist->q_forw;
        emp_remque(qp);
-       free((s_char *)qp);
+       free(qp);
     }
     if (icount == 0) {
-       if (sect.sct_own != 0)
-           mpr(sect.sct_own, "No %ss launched to intercept.\n", def_name);
-       return (destroyed);
+       mpr(sect.sct_own, "No %ss launched to intercept.\n", def_name);
+       return destroyed;
     }
 
     /* attempt to destroy incoming missile */
@@ -330,10 +328,9 @@ msl_intercept(coord x, coord y, natid bombown, int hardtarget,
            mpr(sect.sct_own, "%s launched to intercept %s %s!\n",
                def_name, who, att_name);
        } else {
-           if (sect.sct_own)
-               mpr(sect.sct_own,
-                   "%s launched an %s to intercept the %s %s!\n",
-                   cname(pp->pln_own), def_name, who, att_name);
+           mpr(sect.sct_own,
+               "%s launched an %s to intercept the %s %s!\n",
+               cname(pp->pln_own), def_name, who, att_name);
            mpr(pp->pln_own,
                "%s launched to intercept %s %s arcing towards %s territory!\n",
                def_name, who, att_name, cname(sect.sct_own));
@@ -342,20 +339,18 @@ msl_intercept(coord x, coord y, natid bombown, int hardtarget,
        if (!destroyed &&
            msl_hit(pp, hardtarget, EF_PLANE, news_item, news_item,
                    att_name, x, y, bombown)) {
-           mpr(bombown, "%s destroyed by %s %s!\n", att_name,
-               cname(pp->pln_own), def_name);
-           if (sect.sct_own)
-               mpr(sect.sct_own, "%s %s intercepted!\n", who, att_name);
+           mpr(bombown, "%s destroyed by %s %s!\n",
+               att_name, cname(pp->pln_own), def_name);
+           mpr(sect.sct_own, "%s %s intercepted!\n", who, att_name);
            if (sect.sct_own != pp->pln_own)
                mpr(pp->pln_own, "%s %s intercepted!\n", who, att_name);
            destroyed = 1;
        }
        /* zap the missile */
-       makelost(EF_PLANE, pp->pln_own, pp->pln_uid, pp->pln_x, pp->pln_y);
-       pp->pln_own = 0;
+       pp->pln_effic = 0;
        putplane(pp->pln_uid, pp);
        emp_remque(qp);
-       free((s_char *)qp);
+       free(qp);
        if (destroyed)
            break;
     }
@@ -363,24 +358,23 @@ msl_intercept(coord x, coord y, natid bombown, int hardtarget,
     while (!QEMPTY(intlist)) {
        qp = intlist->q_forw;
        emp_remque(qp);
-       free((s_char *)qp);
+       free(qp);
     }
     if (destroyed)
-       return (destroyed);
+       return destroyed;
     if (icount) {
-       mpr(bombown, "%s made it through %s defenses!\n", att_name,
-           def_name);
-       if (sect.sct_own)
-           mpr(sect.sct_own, "%s made it through %s defenses!\n",
-               att_name, def_name);
+       mpr(bombown, "%s made it through %s defenses!\n",
+           att_name, def_name);
+       mpr(sect.sct_own, "%s made it through %s defenses!\n",
+           att_name, def_name);
     }
-    return (destroyed);
+    return destroyed;
 }
 
 /* Keep launching missiles on list until mindam damage has been done */
 int
 msl_launch_mindam(struct emp_qelem *list, coord x, coord y, int hardtarget,
-                 int type, int mindam, s_char *whatp, int victim,
+                 int type, int mindam, char *whatp, int victim,
                  int mission)
 {
     struct emp_qelem *qp;
@@ -417,14 +411,19 @@ msl_launch_mindam(struct emp_qelem *list, coord x, coord y, int hardtarget,
                        dam += nukedam;
                } else
                    dam += newdam;
+#if 0
+           /*
+            * FIXME want collateral damage on miss (which can't
+            * happen for nuclear war heads), but we get here too when
+            * launch fails or missile is intercepted
+            */
            } else {
                /* Missiles that miss have to hit somewhere! */
                newdam = pln_damage(&plp->plane, x, y, 'p', &nukedam, 0);
-               collateral_damage(x, y, newdam, 0);
+               collateral_damage(x, y, newdam);
+#endif
            }
-           makelost(EF_PLANE, plp->plane.pln_own, plp->plane.pln_uid,
-                    plp->plane.pln_x, plp->plane.pln_y);
-           plp->plane.pln_own = 0;
+           plp->plane.pln_effic = 0;
            putplane(plp->plane.pln_uid, &plp->plane);
            emp_remque(qp);
            free(qp);