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 (getvar(V_SHELL, (s_char *)&fland, EF_LAND) == 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 (getvar(V_MILIT, (s_char *)&item.ship, EF_SHIP) < 1) {
211 pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
214 gun = getvar(V_GUN, (s_char *)&item.ship, EF_SHIP);
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 (getvar(V_SHELL, (s_char *)&item.ship, EF_SHIP) == 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 (getvar(V_GUN, (s_char *)&item.sect, EF_SECTOR) == 0) {
245 pr("Not enough guns in sector %s!\n",
246 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
249 if (getvar(V_SHELL, (s_char *)&item.sect, EF_SECTOR) == 0) {
250 pr("Not enough shells in sector %s!\n",
251 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
254 if (getvar(V_MILIT, (s_char *)&item.sect, EF_SECTOR) < 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 = getvar(V_MILIT, (s_char *)&fship, EF_SHIP)) < 1) {
331 pr("Not enough military for firing crew.\n");
334 gun = getvar(V_GUN, (s_char *)&fship, EF_SHIP);
335 gun = min(gun, fship.shp_glim);
336 if (fship.shp_frnge == 0 || gun == 0) {
337 pr("Insufficient arms.\n");
340 shell = getvar(V_SHELL, (s_char *)&fship, EF_SHIP);
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 putvar(V_SHELL, shell, (s_char *)&fship, EF_SHIP);
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 (getvar(V_SHELL, (s_char *)&fland, EF_LAND) == 0) {
406 pr("%s -- not enough shells\n", prland(&fland));
410 shell = getvar(V_SHELL, (s_char *)&fland, EF_LAND);
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 = getvar(V_GUN, (s_char *)&fland, EF_LAND);
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 = getvar(V_GUN, (s_char *)&fsect, EF_SECTOR)) == 0) {
455 pr("Insufficient arms.\n");
458 shell = getvar(V_SHELL, (s_char *)&fsect, EF_SECTOR);
460 shell += supply_commod(fsect.sct_own, fsect.sct_x,
461 fsect.sct_y, I_SHELL, 1);
466 if (getvar(V_MILIT, (s_char *)&fsect, EF_SECTOR) < 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 putvar(V_SHELL, shell, (s_char *)&fsect, EF_SECTOR);
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);
605 if ((target != targ_sub) ||
606 ((vship.shp_rflags & RET_DCHRGED) == 0))
607 check_retreat_and_do_shipdamage(&vship, dam);
609 shipdamage(&vship, dam);
612 "Country #%d shelled %s in %s for %d damage.\n",
613 player->cnum, prship(&vship),
614 xyas(vship.shp_x, vship.shp_y, vict), dam);
616 pr("Shell%s hit %s in %s for %d damage.\n",
617 splur(shots), prsub(&vship),
618 xyas(vship.shp_x, vship.shp_y, player->cnum), dam);
620 if (vship.shp_effic < SHIP_MINEFF)
621 pr("%s sunk!\n", prsub(&vship));
625 /* Ok, now, check if we had a bogus target. If so,
626 just continue on, since there is no defender. */
627 if (target == targ_bogus)
629 if (attacker == targ_unit) {
630 attacker = targ_land;
631 getsect(fland.lnd_x, fland.lnd_y, &fsect);
634 defend(&fired, &defended, target, attacker, &vsect, &fsect,
635 &vship, &fship, fx, fy, &ndefending);
641 putship(vship.shp_uid, &vship);
644 if ((totaldefdam == 0) && (target == targ_ship))
645 if (vship.shp_rflags & RET_INJURED)
646 retreat_ship(&vship, 'h');
652 if ((target == targ_ship) || (target == targ_sub)) {
653 if (fship.shp_effic > SHIP_MINEFF) {
654 shp_missdef(&fship, vict);
657 putship(fship.shp_uid, &fship);
664 odds = ((double)ndefending) / ((double)nfiring);
667 do_defdam(&fired, odds);
672 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target,
673 enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect,
674 struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
678 int vict, nfiring = 0;
682 if (attacker == targ_land)
683 aown = fsect->sct_own;
685 aown = fship->shp_own;
687 if (target == targ_land)
688 vict = vsect->sct_own;
690 vict = vship->shp_own;
693 (dam = quiet_bigdef(attacker, dl, vict, aown, fx, fy, &nfiring))) {
696 fp = (struct flist *)malloc(sizeof(struct flist));
697 memset(fp, 0, sizeof(struct flist));
702 fp->x = fsect->sct_x;
703 fp->y = fsect->sct_y;
704 fp->type = targ_land;
707 fp->type = targ_ship;
708 fp->uid = fship->shp_uid;
711 emp_insque(&fp->queue, al);
718 do_defdam(struct emp_qelem *list, double odds)
721 int dam, vict, first = 1;
725 struct emp_qelem *qp, *next;
727 for (qp = list->q_forw; qp != list; qp = next) {
729 fp = (struct flist *)qp;
730 if (fp->type == targ_ship) {
731 if (!getship(fp->uid, &ship) || !ship.shp_own)
736 pr("\nDefenders fire back!\n");
739 dam = (odds * (double)fp->defdam);
741 if (fp->type == targ_ship) {
743 pr("Return fire hit %s in %s for %d damage.\n",
745 xyas(ship.shp_x, ship.shp_y, player->cnum), dam);
748 "Return fire hit %s in %s for %d damage.\n",
749 prsub(&ship), xyas(ship.shp_x, ship.shp_y, vict), dam);
750 shipdamage(&ship, dam);
751 putship(ship.shp_uid, &ship);
753 getsect(fp->x, fp->y, §);
755 pr("Return fire hit sector %s for %d damage.\n",
756 xyas(fp->x, fp->y, player->cnum), dam);
757 sectdamage(§, dam, 0);
760 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
761 xyas(fp->x, fp->y, vict), dam);
763 emp_remque(&fp->queue);
769 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
770 coord ax, coord ay, int *nfiring)
773 double range, erange, hitchance;
778 int dam, dam2, rel, rel2;
780 struct sctstr firing;
788 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
789 while (nxtitem(&ni, (caddr_t)&ship)) {
790 if (ship.shp_own == 0)
793 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
794 (attacker == targ_land))
797 rel = getrel(getnatp(ship.shp_own), own);
798 rel2 = getrel(getnatp(ship.shp_own), aown);
799 if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
801 /* Don't shoot yourself */
802 if (ship.shp_own == aown)
804 if (ship.shp_effic < 60)
806 if (getvec(VT_ITEM, vec, (caddr_t)&ship, EF_SHIP) < 0)
809 if (vec[I_MILIT] < 1)
812 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
813 if (vec[I_SHELL] < 3)
814 vec[I_SHELL] += supply_commod(ship.shp_own,
815 ship.shp_x, ship.shp_y,
816 I_SHELL, 3 - vec[I_SHELL]);
817 if (vec[I_SHELL] < 3)
822 if (ship.shp_mobil <= 0)
825 erange = ship.shp_effic *
826 techfact(ship.shp_tech, ((double)ship.shp_frnge))
828 erange = (double)roundrange(erange);
829 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
833 ((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 ptr = (s_char *)&ship;
1011 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
1012 shell = getvar(V_SHELL, ptr, type);
1016 putvar(V_SHELL, shell, ptr, type);
1017 putship(ship.shp_uid, &ship);
1018 mcp = &mchr[(int)ship.shp_type];
1019 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
1020 mobcost = (480.0 / (mobcost +
1021 techfact(ship.shp_tech, mobcost)));
1022 /* mob cost = 1/2 a sect's mob */
1024 ship.shp_mobil -= mobcost;
1026 } else if (fp->type == targ_land) {
1027 getsect(fp->x, fp->y, §);
1028 ptr = (s_char *)§
1031 getland(fp->uid, &land);
1032 ptr = (s_char *)&land;
1035 shell = getvar(V_SHELL, ptr, type);
1039 putvar(V_SHELL, shell, ptr, type);
1040 if (fp->type == targ_ship)
1041 putship(ship.shp_uid, &ship);
1042 else if (fp->type == targ_land)
1045 putland(land.lnd_uid, &land);
1047 emp_remque(&fp->queue);
1054 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1056 struct emp_qelem *qp;
1057 struct flist *fp, *ep;
1060 ep = (struct flist *)elem;
1062 /* Don't put them on the list if they're already there */
1063 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1064 fp = (struct flist *)qp;
1065 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1067 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1073 emp_insque(elem, list);