00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include <config.h>
00041
00042 #include "file.h"
00043 #include "nat.h"
00044 #include "news.h"
00045 #include "optlist.h"
00046 #include "prototypes.h"
00047 #include "sect.h"
00048 #include "ship.h"
00049
00050 #define NOISY 1
00051
00052 static int sb(natid, natid, struct sctstr *, coord, coord, int, int);
00053
00054
00055
00056
00057
00058
00059
00060 int
00061 shipdef(natid att, natid own, coord x, coord y)
00062 {
00063 return sd(att, own, x, y, NOISY, 1, 1);
00064 }
00065
00066 int
00067 sd(natid att, natid own, coord x, coord y, int noisy, int defending,
00068 int usesubs)
00069 {
00070 int nshot;
00071 int range;
00072 double eff;
00073 struct shpstr ship;
00074 struct nstr_item ni;
00075 int shell;
00076 int dam, rel, rel2;
00077
00078 if (own == 0)
00079 return 0;
00080 if (att == own)
00081 return 0;
00082 eff = 1.0;
00083 snxtitem_dist(&ni, EF_SHIP, x, y, 8);
00084 while (nxtitem(&ni, &ship) && eff > 0.30) {
00085 if (ship.shp_own == att)
00086 continue;
00087 if (ship.shp_own == 0)
00088 continue;
00089
00090 rel = getrel(getnatp(ship.shp_own), own);
00091 rel2 = getrel(getnatp(ship.shp_own), att);
00092 if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
00093 continue;
00094 if (ship.shp_effic < 60)
00095 continue;
00096 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) && !usesubs)
00097 continue;
00098 range = roundrange(effrange(ship.shp_frnge, ship.shp_tech));
00099 if (range < ni.curdist)
00100 continue;
00101
00102 shell = ship.shp_item[I_SHELL];
00103 if (shell < ship.shp_glim)
00104 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
00105 I_SHELL, shell - ship.shp_glim);
00106 nshot = MIN(MIN(ship.shp_item[I_GUN], shell), ship.shp_item[I_MILIT]);
00107 nshot = MIN(nshot, ship.shp_glim);
00108 if (nshot <= 0)
00109 continue;
00110 ship.shp_item[I_SHELL] = shell - nshot;
00111 putship(ship.shp_uid, &ship);
00112 if (defending)
00113 nreport(ship.shp_own, N_FIRE_BACK, att, 1);
00114 else
00115 nreport(ship.shp_own, N_FIRE_S_ATTACK, att, 1);
00116 dam = seagun(ship.shp_effic, nshot);
00117 eff *= (1.0 - (0.01 * dam));
00118 if (noisy) {
00119 pr_beep();
00120 pr("Incoming shell%s %d damage!\n",
00121 nshot == 1 ? " does" : "s do", dam);
00122 }
00123 if (noisy || (ship.shp_own != own)) {
00124 if (ship.shp_own == own)
00125 wu(0, own, "%s fired on %s at %s doing %d damage.\n",
00126 prship(&ship), cname(att), xyas(x, y, own), dam);
00127 else {
00128 if (defending)
00129 wu(0, ship.shp_own,
00130 "%s fired on %s at %s in defense of %s, doing %d damage.\n",
00131 prship(&ship), cname(att), xyas(x, y, ship.shp_own),
00132 cname(own), dam);
00133 else
00134 wu(0, ship.shp_own,
00135 "%s supported %s attacks against %s at %s, doing %d damage.\n",
00136 prship(&ship), cname(own), cname(att),
00137 xyas(x, y, ship.shp_own), dam);
00138 }
00139 }
00140 }
00141 return (int)(100 - eff * 100);
00142 }
00143
00144 int
00145 dd(natid att, natid def_own, coord ax, coord ay, int noisy, int defending)
00146 {
00147 int dam, rel, rel2;
00148 struct sctstr firing;
00149 struct nstr_sect ns;
00150
00151 if (opt_NO_FORT_FIRE)
00152 return 0;
00153 if (def_own == 0)
00154 return 0;
00155 if (att == def_own)
00156 return 0;
00157 dam = 0;
00158 snxtsct_dist(&ns, ax, ay, 8);
00159 while (nxtsct(&ns, &firing) && dam < 80) {
00160 if (firing.sct_own == att)
00161 continue;
00162 if (firing.sct_own == 0)
00163 continue;
00164 rel = getrel(getnatp(firing.sct_own), def_own);
00165 rel2 = getrel(getnatp(firing.sct_own), att);
00166 if (firing.sct_own != def_own && (rel != ALLIED || rel2 != AT_WAR))
00167 continue;
00168
00169 dam += sb(att, def_own, &firing, ax, ay, noisy, defending);
00170 }
00171 return dam;
00172 }
00173
00174
00175
00176
00177
00178 static int
00179 sb(natid att, natid def, struct sctstr *sp, coord tx, coord ty, int noisy,
00180 int defending)
00181 {
00182 int damage;
00183 natid own;
00184 int shell;
00185 int range;
00186 int range2, gun;
00187
00188 own = sp->sct_own;
00189 if (own == 0)
00190 return 0;
00191 if (att == own)
00192 return 0;
00193 range = roundrange(fortrange(sp));
00194 range2 = mapdist(sp->sct_x, sp->sct_y, tx, ty);
00195 if (range < range2)
00196 return 0;
00197 gun = sp->sct_item[I_GUN];
00198 if (gun == 0)
00199 return 0;
00200 shell = sp->sct_item[I_SHELL];
00201 if (shell <= 0)
00202 shell += supply_commod(sp->sct_own, sp->sct_x, sp->sct_y,
00203 I_SHELL, 1);
00204 if (shell <= 0)
00205 return 0;
00206 sp->sct_item[I_SHELL] = shell - 1;
00207 putsect(sp);
00208 damage = landgun((int)sp->sct_effic, gun);
00209 if (sp->sct_own != def)
00210 wu(0, sp->sct_own,
00211 "%s fired on %s in %s in defense of %s, doing %d damage!\n",
00212 xyas(sp->sct_x, sp->sct_y, sp->sct_own), cname(att),
00213 xyas(tx, ty, sp->sct_own), cname(def), damage);
00214 if (defending)
00215 nreport(sp->sct_own, N_FIRE_BACK, att, 1);
00216 else
00217 nreport(sp->sct_own, N_FIRE_F_ATTACK, att, 1);
00218 if (noisy)
00219 pr("Incoming shell! %d damage done.\007\n", damage);
00220 return damage;
00221 }