X-Git-Url: http://git.pond.sub.org/?p=empserver;a=blobdiff_plain;f=src%2Flib%2Fsubs%2Fmslsub.c;h=a25f28f68e44e83e5a4af4e94b50c17a83f99f21;hp=9bfbf9fc78cf6824550ecf1ed9f6e6dff84ce736;hb=0b46e31d60f5b60f4dfca7df60574264f6713a3b;hpb=22071b4edb0448bd5b3da73ca7c736315e785b68 diff --git a/src/lib/subs/mslsub.c b/src/lib/subs/mslsub.c index 9bfbf9fc7..a25f28f68 100644 --- a/src/lib/subs/mslsub.c +++ b/src/lib/subs/mslsub.c @@ -1,11 +1,11 @@ /* * Empire - A multi-player, client/server Internet based war game. - * Copyright (C) 1986-2009, Dave Pare, Jeff Bailey, Thomas Ruschak, - * Ken Stevens, Steve McClure + * Copyright (C) 1986-2021, 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, @@ -14,8 +14,7 @@ * 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 . * * --- * @@ -30,24 +29,21 @@ * Known contributors to this file: * Ken Stevens, 1995 * Steve McClure, 1996-2000 - * Markus Armbruster, 2004-2009 + * Markus Armbruster, 2004-2021 */ #include #include -#include "file.h" -#include "land.h" +#include "chance.h" #include "misc.h" -#include "mission.h" #include "nat.h" #include "news.h" #include "nsc.h" #include "nuke.h" #include "optlist.h" -#include "path.h" +#include "plague.h" #include "plane.h" -#include "player.h" #include "prototypes.h" #include "queue.h" #include "sect.h" @@ -59,59 +55,80 @@ msl_launch(struct plnstr *pp, int type, char *what, coord x, coord y, natid victim, int *sublaunchp) { struct shpstr ship; - struct sctstr sect; + struct nukstr nuke; int sublaunch = 0; - char *from; - int dam; + char *base, *in_or_at, *from; mpr(pp->pln_own, "Preparing to launch %s at %s %s %s%s\n", prplane(pp), cname(victim), what, - (type == EF_SHIP || type == EF_PLANE) ? "in " : "", + type != EF_SECTOR ? "in " : "", xyas(x, y, pp->pln_own)); - mpr(pp->pln_own, "\tLaunching from "); if (pp->pln_ship >= 0) { getship(pp->pln_ship, &ship); - mpr(pp->pln_own, "%s in ", prship(&ship)); + base = prship(&ship); + in_or_at = " in "; if (mchr[(int)ship.shp_type].m_flags & M_SUB) { sublaunch = 1; from = "in hatch"; } else from = "on deck"; - mpr(pp->pln_own, "%s\n", - xyas(ship.shp_x, ship.shp_y, pp->pln_own)); } else { if (pp->pln_harden > 0) { - mpr(pp->pln_own, "missile silo at "); + base = "missile silo"; + in_or_at = " at "; from = "in silo"; - } else + } else { + base = in_or_at = ""; from = "on launch pad"; - mpr(pp->pln_own, "%s\n", xyas(pp->pln_x, pp->pln_y, pp->pln_own)); + } } + mpr(pp->pln_own, "\tLaunching from %s%s%s\n", + base, in_or_at, xyas(pp->pln_x, pp->pln_y, pp->pln_own)); + + CANT_HAPPEN(pp->pln_flags & PLN_LAUNCHED); + pp->pln_flags |= PLN_LAUNCHED; + putplane(pp->pln_uid, pp); if (chance((0.05 + (100 - pp->pln_effic) / 100.0) * (1 - techfact(pp->pln_tech, 1.0)))) { mpr(pp->pln_own, "KABOOOOM! Missile explodes %s!\n", from); + if (getnuke(nuk_on_plane(pp), &nuke)) { + mpr(pp->pln_own, "%s lost!\n", prnuke(&nuke)); + nuke.nuk_effic = 0; + putnuke(nuke.nuk_uid, &nuke); + } +#if 0 + /* + * Disabled for now, because it breaks callers that call + * msl_launch() for each member of a list of planes, created + * by msl_sel() or perform_mission(). Damage to the base can + * damage other planes. Any copies of them in the list become + * stale. When msl_launch() modifies and writes back such a + * stale copy, the damage gets wiped out, triggering a seqno + * oops. + */ if (chance(0.33)) { - dam = pln_damage(pp, 'p', 1) / 2; + struct sctstr sect; + int dam; + + dam = pln_damage(pp, 'p', NULL) / 2; 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); + mpr(pp->pln_own, "Explosion damages %s %d%%\n", + xyas(pp->pln_x, pp->pln_y, pp->pln_own), dam); getsect(pp->pln_x, pp->pln_y, §); sectdamage(§, dam); putsect(§); } } +#endif return -1; } - 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 (type != EF_PLANE) @@ -145,8 +162,8 @@ msl_hit(struct plnstr *pp, int hardtarget, int type, hit = 1; } else { hitchance = pln_hitchance(pp, hardtarget, type); - hit = (roll(100) <= hitchance); - mpr(pp->pln_own, "\t%d%% hitchance...%s\n", hitchance, + hit = pct_chance(hitchance); + mpr(pp->pln_own, "\t%d%% hit chance...%s\n", hitchance, hit ? "HIT!" : "miss"); } @@ -190,7 +207,7 @@ msl_sel(struct emp_qelem *list, coord x, coord y, natid victim, if (mission && plane.pln_radius < mapdist(x, y, plane.pln_opx, plane.pln_opy)) continue; - if (getrel(getnatp(plane.pln_own), victim) >= NEUTRAL) + if (relations_with(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)) @@ -199,11 +216,16 @@ msl_sel(struct emp_qelem *list, coord x, coord y, natid victim, continue; if (plane.pln_effic < 100) continue; + if (opt_MARKET) { + if (ontradingblock(EF_PLANE, &plane)) + continue; + } if (!pln_airbase_ok(&plane, 1, 0)) continue; /* got a valid interceptor */ irv = malloc(sizeof(*irv)); irv->load = 0; + irv->pstage = PLG_HEALTHY; irv->pcp = &plchr[(int)plane.pln_type]; irv->plane = plane; emp_insque(&irv->queue, list); @@ -216,7 +238,6 @@ msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch, int news_item) { struct plnstr *pp; - struct plchrstr *pcp; struct emp_qelem *intlist; struct emp_qelem intfoo; struct emp_qelem *qp; @@ -236,8 +257,7 @@ msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch, pp = &ip->plane; if (pp->pln_own != sp->sct_own) continue; - pcp = ip->pcp; - if (mission_pln_equip(ip, NULL, 'i') < 0) { + if (mission_pln_equip(ip, NULL, 0) < 0) { emp_remque(qp); free(qp); continue; @@ -255,8 +275,7 @@ msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch, next = qp->q_forw; ip = (struct plist *)qp; pp = &ip->plane; - pcp = ip->pcp; - if (mission_pln_equip(ip, NULL, 'i') < 0) { + if (mission_pln_equip(ip, NULL, 0) < 0) { emp_remque(qp); free(qp); continue; @@ -287,7 +306,6 @@ msl_intercept(struct plnstr *msl, struct sctstr *sp, int sublaunch, qp = intlist->q_forw; ip = (struct plist *)qp; pp = &ip->plane; - pcp = ip->pcp; mpr(msl->pln_own, "%s %s launched in defense!\n", cname(pp->pln_own), def_name); @@ -347,7 +365,7 @@ msl_abm_intercept(struct plnstr *msl, coord x, coord y, int sublaunch) struct emp_qelem irvlist; getsect(x, y, §); - msl_sel(&irvlist, x, y, msl->pln_own, P_N, P_O, 0); + msl_sel(&irvlist, x, y, msl->pln_own, P_N, 0, 0); return msl_intercept(msl, §, sublaunch, &irvlist, "warhead", "abm", sublaunch ? N_NUKE_SSTOP : N_NUKE_STOP);