2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2000, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * multifire.c: Fire at other sectors/ships
30 * Known contributors to this file:
56 targ_land, targ_ship, targ_sub, targ_unit, targ_bogus
60 struct emp_qelem queue; /* list of fired things */
61 int type; /* ship? otherwise sector */
62 int uid; /* ship uid */
63 coord x, y; /* sector coords */
64 int defdam; /* damage defenders did */
65 int victim; /* who I was shooting at */
74 static void add_to_fired_queue(struct emp_qelem *, struct emp_qelem *);
75 static int defend(struct emp_qelem *al,
77 enum targ_type target,
78 enum targ_type attacker,
82 struct shpstr *fship, int fx, int fy, int *nd);
83 static void do_defdam(struct emp_qelem *, double);
84 static int quiet_bigdef(int, struct emp_qelem *, natid, natid, coord,
86 static void use_ammo(struct emp_qelem *);
115 enum targ_type target, attacker, orig_attacker;
118 struct nstr_item nbst;
124 struct emp_qelem fired, defended;
132 emp_initque(&defended);
134 while ((type != EF_SECTOR) && (type != EF_SHIP) && (type != EF_LAND)) {
135 if (!(p = getstarg(player->argp[1],
136 "Firing from ship(s), sect(s), or land unit(s)? ",
141 if (type == EF_SECTOR) {
142 if (opt_NO_FORT_FIRE) {
143 pr("Fort firing is disabled.\n");
146 orig_attacker = attacker = targ_land;
148 } else if (type == EF_SHIP) {
149 orig_attacker = attacker = targ_ship;
150 } else if (type == EF_LAND) {
151 orig_attacker = attacker = targ_unit;
153 pr("Please type 'sh', 'l', or 'se'!\n");
155 if ((ptr = getstarg(player->argp[2], "Firing from? ", buf)) == 0
159 if (!snxtitem(&nbst, type, ptr))
162 if (player->aborted) {
163 pr("Fire aborted.\n");
166 while (nxtitem(&nbst, (s_char *)&item)) {
167 attacker = orig_attacker;
168 if (attacker == targ_unit) {
169 if (!getland(item.land.lnd_uid, &fland))
171 if (!getsect(item.land.lnd_x, item.land.lnd_y, &fsect))
173 if (item.land.lnd_own != player->cnum)
176 if (fland.lnd_frg == 0) {
177 pr("Unit %d cannot fire!\n", fland.lnd_uid);
180 if (lnd_getmil(&fland) < 1) {
181 pr("Unit %d cannot fire because it has no military!\n",
185 if (fland.lnd_ship >= 0) {
186 pr("Unit %d cannot fire because it is on a ship!\n",
190 if (fland.lnd_land >= 0) {
191 pr("Unit %d cannot fire because it is on a land unit!\n",
195 if (fland.lnd_effic < LAND_MINFIREEFF) {
196 pr("Unit %d cannot fire because it is less than %d%% efficient\n", fland.lnd_uid, LAND_MINFIREEFF);
199 resupply_commod(&fland, I_SHELL); /* Get more shells */
200 putland(fland.lnd_uid, &fland);
201 if (fland.lnd_item[I_SHELL] == 0) {
202 pr("%s -- not enough shells\n", prland(&fland));
205 } else if (attacker == targ_ship) {
206 if (!getship(item.ship.shp_uid, &fship))
208 if (item.ship.shp_own != player->cnum)
210 if (item.ship.shp_item[I_MILIT] < 1) {
211 pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
214 gun = item.ship.shp_item[I_GUN];
215 gun = min(gun, item.ship.shp_glim);
216 if (item.ship.shp_frnge == 0) {
217 pr("Ships %d cannot fire guns!\n", item.ship.shp_uid);
221 pr("Not enough guns on ship #%d\n", item.ship.shp_uid);
224 if (item.ship.shp_item[I_SHELL] == 0) {
225 pr("Not enough shells on ship #%d\n", item.ship.shp_uid);
228 if (item.ship.shp_effic < 60) {
229 pr("Ship #%d is crippled!\n", item.ship.shp_uid);
232 fshipno = fship.shp_uid;
233 } else if (attacker == targ_land) {
234 if (!getsect(item.sect.sct_x, item.sect.sct_y, &fsect))
236 if (item.sect.sct_own != player->cnum)
238 if (item.sect.sct_type != SCT_FORTR)
240 if (item.sect.sct_effic < ((u_char)FORTEFF)) {
241 pr("Fort not efficient enough to fire!\n");
244 if (item.sect.sct_item[I_GUN] == 0) {
245 pr("Not enough guns in sector %s!\n",
246 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
249 if (item.sect.sct_item[I_SHELL] == 0) {
250 pr("Not enough shells in sector %s!\n",
251 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
254 if (item.sect.sct_item[I_MILIT] < 5) {
255 pr("Not enough military in sector %s!\n",
256 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
259 pr("\nSector %s firing\n",
260 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
262 if ((ptr = getstarg(player->argp[3], "Firing at? ", buf)) == 0
265 if (player->aborted) {
266 pr("Fire aborted.\n");
270 (void)strcpy(vbuf, ptr);
275 if (target == targ_ship) {
276 vshipno = atoi(vbuf);
277 if (vshipno < 0 || !getship(vshipno, &vship) ||
279 pr("No such ship exists!\n");
282 target = (mchr[(int)vship.shp_type].m_flags & M_SUB) ?
283 targ_sub : targ_ship;
284 vict = vship.shp_own;
287 if (!getsect(x, y, &vsect)) {
288 pr("No such sector exists!\n");
292 if (!sarg_xy(vbuf, &x, &y) || !getsect(x, y, &vsect)) {
293 pr("No such sector exists!\n");
296 /* We check the sector type, but we only use it for damage, not
297 reporting. That way, you don't get extra information you wouldn't
298 normally get. Besides, what if they want to slam water? :) */
299 if (vsect.sct_type == SCT_SANCT || vsect.sct_type == SCT_WATER)
303 vict = vsect.sct_own;
307 if (attacker == targ_ship) {
308 shots = -1; /* convert to max later */
309 if (fship.shp_own != player->cnum) {
310 pr("Not your ship!\n");
313 if (target == targ_sub || target == targ_ship) {
314 if (fship.shp_uid == vship.shp_uid) {
315 pr("You can't fire upon yourself!\n");
322 attacker = (mchr[fship.shp_type].m_flags & M_SUB) ?
323 targ_sub : targ_ship;
324 if (attacker == targ_sub){
325 pr("Subs may not fire normally.. use torpedo.\n");
329 attacker = targ_ship;
330 if ((mil = fship.shp_item[I_MILIT]) < 1) {
331 pr("Not enough military for firing crew.\n");
334 gun = fship.shp_item[I_GUN];
335 gun = min(gun, fship.shp_glim);
336 if (fship.shp_frnge == 0 || gun == 0) {
337 pr("Insufficient arms.\n");
340 shell = fship.shp_item[I_SHELL];
342 shell += supply_commod(fship.shp_own, fship.shp_x,
343 fship.shp_y, I_SHELL, 2 - shell);
348 if (fship.shp_effic < 60) {
349 pr("Ship #%d is crippled (%d%%)\n", fshipno,
353 range = techfact(fship.shp_tech,
354 (double)fship.shp_frnge / 2.0);
355 range2 = (double)roundrange(range);
356 pr("range is %.2f (%.2f)\n", range2, range);
357 if (target == targ_sub) {
358 if ((mchr[(int)fship.shp_type].m_flags & M_DCH) == 0) {
359 pr("A %s can't drop depth charges!\n",
360 mchr[(int)fship.shp_type].m_name);
364 pr("Not enough shells for depth charge!\n");
368 gun = min(gun, shell * 2);
369 gun = min(gun, mil / 2);
371 if (shots > gun || shots < 0)
373 else if (shots == 0) {
374 pr("No shots fired.\n");
377 guneff = seagun(fship.shp_effic, shots);
379 shell -= ldround(((double)shots) / 2.0, 1);
380 fship.shp_item[I_SHELL] = shell;
381 putship(fship.shp_uid, &fship);
382 if (opt_NOMOBCOST == 0)
383 fship.shp_mobil = max(fship.shp_mobil - 15, -100);
384 } else if (attacker == targ_unit) {
385 if (fland.lnd_own != player->cnum) {
386 pr("Not your unit!\n");
390 if (target == targ_land) {
391 if (fland.lnd_x == vsect.sct_x
392 && fland.lnd_y == vsect.sct_y) {
393 pr("You can't fire upon yourself!\n");
401 if (fland.lnd_frg == 0) {
402 pr("Unit %d cannot fire!\n", fland.lnd_uid);
405 if (fland.lnd_item[I_SHELL] == 0) {
406 pr("%s -- not enough shells\n", prland(&fland));
410 shell = fland.lnd_item[I_SHELL];
412 range = techfact((int)fland.lnd_tech,
413 (double)fland.lnd_frg / 2.0);
414 range2 = (double)roundrange(range);
415 pr("range is %.2f (%.2f)\n", range2, range);
416 if (target == targ_sub) {
417 pr("A %s can't drop depth charges!\n",
418 lchr[(int)fland.lnd_type].l_name);
422 gun = fland.lnd_item[I_GUN];
424 pr("%s -- not enough guns\n", prland(&fland));
428 dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
429 fland.lnd_ammo, shell);
430 if (target == targ_ship) {
431 if (chance(((double)fland.lnd_acc) / 100.0))
432 dam = ldround(((double)dam / 2.0), 1);
435 resupply_commod(&fland, I_SHELL); /* Get more shells */
436 putland(fland.lnd_uid, &fland);
440 if (fsect.sct_own != player->cnum ||
441 fsect.sct_type != SCT_FORTR) {
442 pr("No fortress at %s\n", xyas(fsect.sct_x,
443 fsect.sct_y, player->cnum));
446 if (target == targ_land) {
447 if (fsect.sct_x == vsect.sct_x
448 && fsect.sct_y == vsect.sct_y) {
449 pr("You can't fire upon yourself!\n");
453 attacker = targ_land;
454 if ((gun = fsect.sct_item[I_GUN]) == 0) {
455 pr("Insufficient arms.\n");
458 shell = fsect.sct_item[I_SHELL];
460 shell += supply_commod(fsect.sct_own, fsect.sct_x,
461 fsect.sct_y, I_SHELL, 1);
466 if (fsect.sct_item[I_MILIT] < 5) {
467 pr("Not enough military for firing crew.\n");
470 if (target == targ_sub) {
471 pr("Target ship not sighted!\n");
476 range = tfactfire(player->cnum, 7.0);
477 if (fsect.sct_effic > 59)
479 range2 = (double)roundrange(range);
480 pr("range is %.2f (%.2f)\n", range2, range);
481 guneff = landgun((int)fsect.sct_effic, gun);
484 fsect.sct_item[I_SHELL] = shell;
487 trange = mapdist(x, y, fx, fy);
488 if (trange > range2) {
489 pr("Target out of range.\n");
494 pr("Target out of range. Thud.\n");
497 pr("Target ship out of range. Splash.\n");
506 fland.lnd_mission = 0;
507 putland(fland.lnd_uid, &fland);
510 fship.shp_mission = 0;
511 putship(fship.shp_uid, &fship);
516 if (target == targ_bogus) {
517 if (vsect.sct_type == SCT_SANCT) {
518 pr("%s is a %s!!\n", vbuf,
519 dchr[SCT_SANCT].d_name);
521 } else if (vsect.sct_type == SCT_WATER) {
522 pr("You must specify a ship in sector %s!\n",
530 if (!trechk(player->cnum, vict, SEAFIR))
534 if (!trechk(player->cnum, vict, SUBFIR))
539 if (!trechk(player->cnum, vict, LANFIR))
547 if (target == targ_land) {
548 natp = getnatp(player->cnum);
549 rel = getrel(natp, vict);
550 if ((rel != AT_WAR) && (player->cnum != vict) &&
551 (vict) && (vsect.sct_oldown != player->cnum)) {
552 pr("You're not at war with them!\n");
562 if (vship.shp_rflags & RET_DCHRGED)
563 retreat_ship(&vship, 'd');
568 prb = (double)(range2 ? (trange / range2) : 1.0);
577 pr("Wind deflects shell%s.\n", splur(shots));
578 /* dam = (int)((double)dam / 2.0);*/
581 (double)((double)(90 - (random() % 11)) /
591 nreport(player->cnum, N_SCT_SHELL, vict, 1);
592 if (vict && vict != player->cnum)
594 "Country #%d shelled sector %s for %d damage.\n",
595 player->cnum, xyas(x, y, vict), dam);
596 pr("Shell%s hit sector %s for %d damage.\n",
597 splur(shots), xyas(x, y, player->cnum), dam);
598 /* Ok, it wasn't a bogus target, so do damage. */
599 if (target != targ_bogus)
600 sectdamage(&vsect, dam, 0);
603 nreport(player->cnum, N_SHP_SHELL, vict, 1);
606 if ((target != targ_sub) ||
607 ((vship.shp_rflags & RET_DCHRGED) == 0))
608 check_retreat_and_do_shipdamage(&vship, dam);
610 shipdamage(&vship, dam);
613 "Country #%d shelled %s in %s for %d damage.\n",
614 player->cnum, prship(&vship),
615 xyas(vship.shp_x, vship.shp_y, vict), dam);
617 pr("Shell%s hit %s in %s for %d damage.\n",
618 splur(shots), prsub(&vship),
619 xyas(vship.shp_x, vship.shp_y, player->cnum), dam);
621 if (vship.shp_effic < SHIP_MINEFF)
622 pr("%s sunk!\n", prsub(&vship));
626 /* Ok, now, check if we had a bogus target. If so,
627 just continue on, since there is no defender. */
628 if (target == targ_bogus)
630 if (attacker == targ_unit) {
631 attacker = targ_land;
632 getsect(fland.lnd_x, fland.lnd_y, &fsect);
635 defend(&fired, &defended, target, attacker, &vsect, &fsect,
636 &vship, &fship, fx, fy, &ndefending);
642 putship(vship.shp_uid, &vship);
645 if ((totaldefdam == 0) && (target == targ_ship))
646 if (vship.shp_rflags & RET_INJURED)
647 retreat_ship(&vship, 'h');
653 if ((target == targ_ship) || (target == targ_sub)) {
654 if (fship.shp_effic > SHIP_MINEFF) {
655 shp_missdef(&fship, vict);
658 putship(fship.shp_uid, &fship);
665 odds = ((double)ndefending) / ((double)nfiring);
668 do_defdam(&fired, odds);
673 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target,
674 enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect,
675 struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
679 int vict, nfiring = 0;
683 if (attacker == targ_land)
684 aown = fsect->sct_own;
686 aown = fship->shp_own;
688 if (target == targ_land)
689 vict = vsect->sct_own;
691 vict = vship->shp_own;
694 (dam = quiet_bigdef(attacker, dl, vict, aown, fx, fy, &nfiring))) {
697 fp = (struct flist *)malloc(sizeof(struct flist));
698 memset(fp, 0, sizeof(struct flist));
703 fp->x = fsect->sct_x;
704 fp->y = fsect->sct_y;
705 fp->type = targ_land;
708 fp->type = targ_ship;
709 fp->uid = fship->shp_uid;
712 emp_insque(&fp->queue, al);
719 do_defdam(struct emp_qelem *list, double odds)
722 int dam, vict, first = 1;
726 struct emp_qelem *qp, *next;
728 for (qp = list->q_forw; qp != list; qp = next) {
730 fp = (struct flist *)qp;
731 if (fp->type == targ_ship) {
732 if (!getship(fp->uid, &ship) || !ship.shp_own)
737 pr("\nDefenders fire back!\n");
740 dam = (odds * (double)fp->defdam);
742 if (fp->type == targ_ship) {
744 pr("Return fire hit %s in %s for %d damage.\n",
746 xyas(ship.shp_x, ship.shp_y, player->cnum), dam);
749 "Return fire hit %s in %s for %d damage.\n",
750 prsub(&ship), xyas(ship.shp_x, ship.shp_y, vict), dam);
751 shipdamage(&ship, dam);
752 putship(ship.shp_uid, &ship);
754 getsect(fp->x, fp->y, §);
756 pr("Return fire hit sector %s for %d damage.\n",
757 xyas(fp->x, fp->y, player->cnum), dam);
758 sectdamage(§, dam, 0);
761 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
762 xyas(fp->x, fp->y, vict), dam);
764 emp_remque(&fp->queue);
770 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
771 coord ax, coord ay, int *nfiring)
774 double range, erange, hitchance;
779 int dam, dam2, rel, rel2;
781 struct sctstr firing;
789 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
790 while (nxtitem(&ni, (caddr_t)&ship)) {
791 if (ship.shp_own == 0)
794 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
795 (attacker == targ_land))
798 rel = getrel(getnatp(ship.shp_own), own);
799 rel2 = getrel(getnatp(ship.shp_own), aown);
800 if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
802 /* Don't shoot yourself */
803 if (ship.shp_own == aown)
805 if (ship.shp_effic < 60)
807 if (getvec(VT_ITEM, vec, (caddr_t)&ship, EF_SHIP) < 0)
810 if (vec[I_MILIT] < 1)
813 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
814 if (vec[I_SHELL] < 3)
815 vec[I_SHELL] += supply_commod(ship.shp_own,
816 ship.shp_x, ship.shp_y,
817 I_SHELL, 3 - vec[I_SHELL]);
818 if (vec[I_SHELL] < 3)
823 if (ship.shp_mobil <= 0)
826 erange = ship.shp_effic *
827 techfact(ship.shp_tech, ((double)ship.shp_frnge))
829 erange = (double)roundrange(erange);
830 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
833 if (!line_of_sight((s_char **)0, ship.shp_x, ship.shp_y, ax, ay))
837 fp = (struct flist *)malloc(sizeof(struct flist));
838 memset(fp, 0, sizeof(struct flist));
839 fp->type = targ_ship;
840 fp->uid = ship.shp_uid;
841 add_to_fired_queue(&fp->queue, list);
843 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
845 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
846 if (!chance(hitchance))
849 dam += TORP_DAMAGE();
851 range = techfact(ship.shp_tech,
852 ship.shp_frnge * ship.shp_effic / 200.0);
853 range = (double)roundrange(range);
854 if (range < ni.curdist)
856 /* must have gun, shell, and milit to fire */
857 if (vec[I_SHELL] < 1)
858 vec[I_SHELL] += supply_commod(ship.shp_own,
859 ship.shp_x, ship.shp_y,
861 /* only need 1 shell, so don't check that */
862 if (vec[I_SHELL] < 1)
864 nshot = min(vec[I_GUN], vec[I_MILIT]);
865 nshot = min(nshot, ship.shp_glim);
869 fp = (struct flist *)malloc(sizeof(struct flist));
870 memset(fp, 0, sizeof(struct flist));
871 fp->type = targ_ship;
872 fp->uid = ship.shp_uid;
873 add_to_fired_queue(&fp->queue, list);
874 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
875 dam += seagun(ship.shp_effic, nshot);
878 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
879 while (nxtitem(&ni, (caddr_t)&land)) {
880 if (land.lnd_own == 0)
882 if (land.lnd_effic < LAND_MINFIREEFF)
884 /* Can't fire if on a ship */
885 if (land.lnd_ship >= 0)
887 if (land.lnd_land >= 0)
889 /* Gotta have military */
890 if (lnd_getmil(&land) < 1)
892 /* Don't shoot yourself */
893 if (land.lnd_own == aown)
896 rel = getrel(getnatp(land.lnd_own), own);
897 rel2 = getrel(getnatp(land.lnd_own), aown);
899 if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
903 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
904 range = (double)roundrange(range);
905 if (range < ni.curdist)
909 if (!has_supply(&land))
912 if (getvec(VT_ITEM, vec, (caddr_t)&land, EF_LAND) < 0)
915 if (vec[I_MILIT] == 0 || vec[I_SHELL] == 0 || vec[I_GUN] == 0)
918 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, vec[I_GUN],
919 land.lnd_ammo, vec[I_SHELL]);
922 fp = (struct flist *)malloc(sizeof(struct flist));
923 memset(fp, 0, sizeof(struct flist));
924 fp->type = targ_unit;
925 fp->uid = land.lnd_uid;
926 add_to_fired_queue(&fp->queue, list);
928 putland(land.lnd_uid, &land);
929 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
934 * Determine if any nearby gun-equipped sectors are within
935 * range and able to fire at an attacker. Firing sectors
936 * need to have guns, shells, and military. Sector being
937 * attacked is x,y -- attacker is at ax,ay.
940 if (!opt_NO_FORT_FIRE) {
941 snxtsct_dist(&ns, ax, ay, 8);
942 while (nxtsct(&ns, &firing)) {
944 if (firing.sct_type != SCT_FORTR)
946 if (firing.sct_own == 0)
948 rel = getrel(getnatp(firing.sct_own), own);
949 rel2 = getrel(getnatp(firing.sct_own), aown);
951 if ((firing.sct_own != own) &&
952 ((rel != ALLIED) || (rel2 != AT_WAR)))
954 /* Don't shoot yourself */
955 if (firing.sct_own == aown)
957 tech = tfactfire(firing.sct_own, 1.0);
959 if (firing.sct_effic > 59) /* fort bonus */
961 range = (double)roundrange(range);
962 if (range < ns.curdist)
964 if (getvec(VT_ITEM, vec, (caddr_t)&firing, EF_SECTOR) < 0)
966 if (vec[I_SHELL] < 1)
967 vec[I_SHELL] += supply_commod(firing.sct_own,
968 firing.sct_x, firing.sct_y,
970 if (vec[I_GUN] == 0 || vec[I_MILIT] < 5 || vec[I_SHELL] == 0)
973 fp = (struct flist *)malloc(sizeof(struct flist));
974 memset(fp, 0, sizeof(struct flist));
975 fp->x = firing.sct_x;
976 fp->y = firing.sct_y;
977 fp->type = targ_land;
978 add_to_fired_queue(&fp->queue, list);
979 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
983 dam += landgun((int)firing.sct_effic, gun);
987 return ((*nfiring) == 0 ? 0 : (dam / (*nfiring)));
991 use_ammo(struct emp_qelem *list)
993 struct emp_qelem *qp, *next;
1001 struct mchrstr *mcp;
1003 /* use 1 shell from everyone */
1004 for (qp = list->q_forw; qp != list; qp = next) {
1006 fp = (struct flist *)qp;
1007 if (fp->type == targ_ship) {
1008 getship(fp->uid, &ship);
1009 item = ship.shp_item;
1010 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
1011 shell = item[I_SHELL];
1015 item[I_SHELL] = shell;
1016 putship(ship.shp_uid, &ship);
1017 mcp = &mchr[(int)ship.shp_type];
1018 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
1019 mobcost = (480.0 / (mobcost +
1020 techfact(ship.shp_tech, mobcost)));
1021 /* mob cost = 1/2 a sect's mob */
1023 ship.shp_mobil -= mobcost;
1025 } else if (fp->type == targ_land) {
1026 getsect(fp->x, fp->y, §);
1027 item = sect.sct_item;
1029 getland(fp->uid, &land);
1030 item = land.lnd_item;
1032 shell = item[I_SHELL];
1036 item[I_SHELL] = shell;
1037 if (fp->type == targ_ship)
1038 putship(ship.shp_uid, &ship);
1039 else if (fp->type == targ_land)
1042 putland(land.lnd_uid, &land);
1044 emp_remque(&fp->queue);
1051 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1053 struct emp_qelem *qp;
1054 struct flist *fp, *ep;
1057 ep = (struct flist *)elem;
1059 /* Don't put them on the list if they're already there */
1060 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1061 fp = (struct flist *)qp;
1062 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1064 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1070 emp_insque(elem, list);