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);
832 if (!line_of_sight((s_char **)0, ship.shp_x, ship.shp_y, ax, ay))
836 fp = (struct flist *)malloc(sizeof(struct flist));
837 memset(fp, 0, sizeof(struct flist));
838 fp->type = targ_ship;
839 fp->uid = ship.shp_uid;
840 add_to_fired_queue(&fp->queue, list);
842 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
844 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
845 if (!chance(hitchance))
848 dam += TORP_DAMAGE();
850 range = techfact(ship.shp_tech,
851 ship.shp_frnge * ship.shp_effic / 200.0);
852 range = (double)roundrange(range);
853 if (range < ni.curdist)
855 /* must have gun, shell, and milit to fire */
856 if (vec[I_SHELL] < 1)
857 vec[I_SHELL] += supply_commod(ship.shp_own,
858 ship.shp_x, ship.shp_y,
860 /* only need 1 shell, so don't check that */
861 if (vec[I_SHELL] < 1)
863 nshot = min(vec[I_GUN], vec[I_MILIT]);
864 nshot = min(nshot, ship.shp_glim);
868 fp = (struct flist *)malloc(sizeof(struct flist));
869 memset(fp, 0, sizeof(struct flist));
870 fp->type = targ_ship;
871 fp->uid = ship.shp_uid;
872 add_to_fired_queue(&fp->queue, list);
873 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
874 dam += seagun(ship.shp_effic, nshot);
877 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
878 while (nxtitem(&ni, (caddr_t)&land)) {
879 if (land.lnd_own == 0)
881 if (land.lnd_effic < LAND_MINFIREEFF)
883 /* Can't fire if on a ship */
884 if (land.lnd_ship >= 0)
886 if (land.lnd_land >= 0)
888 /* Gotta have military */
889 if (lnd_getmil(&land) < 1)
891 /* Don't shoot yourself */
892 if (land.lnd_own == aown)
895 rel = getrel(getnatp(land.lnd_own), own);
896 rel2 = getrel(getnatp(land.lnd_own), aown);
898 if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
902 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
903 range = (double)roundrange(range);
904 if (range < ni.curdist)
908 if (!has_supply(&land))
911 if (getvec(VT_ITEM, vec, (caddr_t)&land, EF_LAND) < 0)
914 if (vec[I_MILIT] == 0 || vec[I_SHELL] == 0 || vec[I_GUN] == 0)
917 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, vec[I_GUN],
918 land.lnd_ammo, vec[I_SHELL]);
921 fp = (struct flist *)malloc(sizeof(struct flist));
922 memset(fp, 0, sizeof(struct flist));
923 fp->type = targ_unit;
924 fp->uid = land.lnd_uid;
925 add_to_fired_queue(&fp->queue, list);
927 putland(land.lnd_uid, &land);
928 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
933 * Determine if any nearby gun-equipped sectors are within
934 * range and able to fire at an attacker. Firing sectors
935 * need to have guns, shells, and military. Sector being
936 * attacked is x,y -- attacker is at ax,ay.
939 if (!opt_NO_FORT_FIRE) {
940 snxtsct_dist(&ns, ax, ay, 8);
941 while (nxtsct(&ns, &firing)) {
943 if (firing.sct_type != SCT_FORTR)
945 if (firing.sct_own == 0)
947 rel = getrel(getnatp(firing.sct_own), own);
948 rel2 = getrel(getnatp(firing.sct_own), aown);
950 if ((firing.sct_own != own) &&
951 ((rel != ALLIED) || (rel2 != AT_WAR)))
953 /* Don't shoot yourself */
954 if (firing.sct_own == aown)
956 tech = tfactfire(firing.sct_own, 1.0);
958 if (firing.sct_effic > 59) /* fort bonus */
960 range = (double)roundrange(range);
961 if (range < ns.curdist)
963 if (getvec(VT_ITEM, vec, (caddr_t)&firing, EF_SECTOR) < 0)
965 if (vec[I_SHELL] < 1)
966 vec[I_SHELL] += supply_commod(firing.sct_own,
967 firing.sct_x, firing.sct_y,
969 if (vec[I_GUN] == 0 || vec[I_MILIT] < 5 || vec[I_SHELL] == 0)
972 fp = (struct flist *)malloc(sizeof(struct flist));
973 memset(fp, 0, sizeof(struct flist));
974 fp->x = firing.sct_x;
975 fp->y = firing.sct_y;
976 fp->type = targ_land;
977 add_to_fired_queue(&fp->queue, list);
978 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
982 dam += landgun((int)firing.sct_effic, gun);
986 return ((*nfiring) == 0 ? 0 : (dam / (*nfiring)));
990 use_ammo(struct emp_qelem *list)
992 struct emp_qelem *qp, *next;
1000 struct mchrstr *mcp;
1002 /* use 1 shell from everyone */
1003 for (qp = list->q_forw; qp != list; qp = next) {
1005 fp = (struct flist *)qp;
1006 if (fp->type == targ_ship) {
1007 getship(fp->uid, &ship);
1008 ptr = (s_char *)&ship;
1010 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
1011 shell = getvar(V_SHELL, ptr, type);
1015 putvar(V_SHELL, shell, ptr, type);
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 ptr = (s_char *)§
1030 getland(fp->uid, &land);
1031 ptr = (s_char *)&land;
1034 shell = getvar(V_SHELL, ptr, type);
1038 putvar(V_SHELL, shell, ptr, type);
1039 if (fp->type == targ_ship)
1040 putship(ship.shp_uid, &ship);
1041 else if (fp->type == targ_land)
1044 putland(land.lnd_uid, &land);
1046 emp_remque(&fp->queue);
1053 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1055 struct emp_qelem *qp;
1056 struct flist *fp, *ep;
1059 ep = (struct flist *)elem;
1061 /* Don't put them on the list if they're already there */
1062 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1063 fp = (struct flist *)qp;
1064 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1066 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1072 emp_insque(elem, list);