2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2004, 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 if (opt_NOMOBCOST == 0)
382 fship.shp_mobil = max(fship.shp_mobil - 15, -100);
383 putship(fship.shp_uid, &fship);
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;
778 int dam, dam2, rel, rel2;
780 struct sctstr firing;
788 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
789 while (nxtitem(&ni, &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)
807 gun = ship.shp_item[I_GUN];
808 shell = ship.shp_item[I_SHELL];
810 if (ship.shp_item[I_MILIT] < 1)
813 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
814 if (shell < SHP_TORP_SHELLS)
815 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
816 I_SHELL, SHP_TORP_SHELLS - shell);
817 if (shell < SHP_TORP_SHELLS)
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 */
857 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
859 /* only need 1 shell, so don't check that */
862 nshot = min(gun, ship.shp_item[I_MILIT]);
863 nshot = min(nshot, ship.shp_glim);
867 fp = (struct flist *)malloc(sizeof(struct flist));
868 memset(fp, 0, sizeof(struct flist));
869 fp->type = targ_ship;
870 fp->uid = ship.shp_uid;
871 add_to_fired_queue(&fp->queue, list);
872 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
873 dam += seagun(ship.shp_effic, nshot);
876 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
877 while (nxtitem(&ni, &land)) {
878 if (land.lnd_own == 0)
880 if (land.lnd_effic < LAND_MINFIREEFF)
882 /* Can't fire if on a ship */
883 if (land.lnd_ship >= 0)
885 if (land.lnd_land >= 0)
887 /* Gotta have military */
888 if (lnd_getmil(&land) < 1)
890 /* Don't shoot yourself */
891 if (land.lnd_own == aown)
894 rel = getrel(getnatp(land.lnd_own), own);
895 rel2 = getrel(getnatp(land.lnd_own), aown);
897 if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
901 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
902 range = (double)roundrange(range);
903 if (range < ni.curdist)
907 if (!has_supply(&land))
910 gun = land.lnd_item[I_GUN];
911 shell = land.lnd_item[I_SHELL];
913 if (land.lnd_item[I_MILIT] == 0 || shell == 0 || gun == 0)
916 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, gun,
917 land.lnd_ammo, shell);
920 fp = (struct flist *)malloc(sizeof(struct flist));
921 memset(fp, 0, sizeof(struct flist));
922 fp->type = targ_unit;
923 fp->uid = land.lnd_uid;
924 add_to_fired_queue(&fp->queue, list);
926 putland(land.lnd_uid, &land);
927 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
932 * Determine if any nearby gun-equipped sectors are within
933 * range and able to fire at an attacker. Firing sectors
934 * need to have guns, shells, and military. Sector being
935 * attacked is x,y -- attacker is at ax,ay.
938 if (!opt_NO_FORT_FIRE) {
939 snxtsct_dist(&ns, ax, ay, 8);
940 while (nxtsct(&ns, &firing)) {
942 if (firing.sct_type != SCT_FORTR)
944 if (firing.sct_own == 0)
946 rel = getrel(getnatp(firing.sct_own), own);
947 rel2 = getrel(getnatp(firing.sct_own), aown);
949 if ((firing.sct_own != own) &&
950 ((rel != ALLIED) || (rel2 != AT_WAR)))
952 /* Don't shoot yourself */
953 if (firing.sct_own == aown)
955 tech = tfactfire(firing.sct_own, 1.0);
957 if (firing.sct_effic > 59) /* fort bonus */
959 range = (double)roundrange(range);
960 if (range < ns.curdist)
963 gun = firing.sct_item[I_GUN];
964 shell = firing.sct_item[I_SHELL];
967 shell += supply_commod(firing.sct_own,
968 firing.sct_x, firing.sct_y,
970 if (gun == 0 || firing.sct_item[I_MILIT] < 5 || 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);
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 item = ship.shp_item;
1009 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
1010 shell = item[I_SHELL];
1011 shell -= SHP_TORP_SHELLS - 1;
1014 item[I_SHELL] = shell;
1015 putship(ship.shp_uid, &ship);
1016 mcp = &mchr[(int)ship.shp_type];
1017 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
1018 mobcost = (480.0 / (mobcost +
1019 techfact(ship.shp_tech, mobcost)));
1020 /* mob cost = 1/2 a sect's mob */
1022 ship.shp_mobil -= mobcost;
1024 } else if (fp->type == targ_land) {
1025 getsect(fp->x, fp->y, §);
1026 item = sect.sct_item;
1028 getland(fp->uid, &land);
1029 item = land.lnd_item;
1031 shell = item[I_SHELL];
1035 item[I_SHELL] = shell;
1036 if (fp->type == targ_ship)
1037 putship(ship.shp_uid, &ship);
1038 else if (fp->type == targ_land)
1041 putland(land.lnd_uid, &land);
1043 emp_remque(&fp->queue);
1050 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1052 struct emp_qelem *qp;
1053 struct flist *fp, *ep;
1056 ep = (struct flist *)elem;
1058 /* Don't put them on the list if they're already there */
1059 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1060 fp = (struct flist *)qp;
1061 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1063 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1069 emp_insque(elem, list);