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:
54 targ_land, targ_ship, targ_sub, targ_unit, targ_bogus
58 struct emp_qelem queue; /* list of fired things */
59 int type; /* ship? otherwise sector */
60 int uid; /* ship uid */
61 coord x, y; /* sector coords */
62 int defdam; /* damage defenders did */
63 int victim; /* who I was shooting at */
72 static void add_to_fired_queue(struct emp_qelem *, struct emp_qelem *);
73 static int defend(struct emp_qelem *al,
75 enum targ_type target,
76 enum targ_type attacker,
80 struct shpstr *fship, int fx, int fy, int *nd);
81 static void do_defdam(struct emp_qelem *, double);
82 static int quiet_bigdef(int, struct emp_qelem *, natid, natid, coord,
84 static void use_ammo(struct emp_qelem *);
113 enum targ_type target, attacker, orig_attacker;
116 struct nstr_item nbst;
122 struct emp_qelem fired, defended;
130 emp_initque(&defended);
132 while ((type != EF_SECTOR) && (type != EF_SHIP) && (type != EF_LAND)) {
133 if (!(p = getstarg(player->argp[1],
134 "Firing from ship(s), sect(s), or land unit(s)? ",
139 if (type == EF_SECTOR) {
140 if (opt_NO_FORT_FIRE) {
141 pr("Fort firing is disabled.\n");
144 orig_attacker = attacker = targ_land;
146 } else if (type == EF_SHIP) {
147 orig_attacker = attacker = targ_ship;
148 } else if (type == EF_LAND) {
149 orig_attacker = attacker = targ_unit;
151 pr("Please type 'sh', 'l', or 'se'!\n");
153 if ((ptr = getstarg(player->argp[2], "Firing from? ", buf)) == 0
157 if (!snxtitem(&nbst, type, ptr))
160 if (player->aborted) {
161 pr("Fire aborted.\n");
164 while (nxtitem(&nbst, (s_char *)&item)) {
165 attacker = orig_attacker;
166 if (attacker == targ_unit) {
167 if (!getland(item.land.lnd_uid, &fland))
169 if (!getsect(item.land.lnd_x, item.land.lnd_y, &fsect))
171 if (item.land.lnd_own != player->cnum)
174 if (fland.lnd_frg == 0) {
175 pr("Unit %d cannot fire!\n", fland.lnd_uid);
178 if (lnd_getmil(&fland) < 1) {
179 pr("Unit %d cannot fire because it has no military!\n",
183 if (fland.lnd_ship >= 0) {
184 pr("Unit %d cannot fire because it is on a ship!\n",
188 if (fland.lnd_land >= 0) {
189 pr("Unit %d cannot fire because it is on a land unit!\n",
193 if (fland.lnd_effic < LAND_MINFIREEFF) {
194 pr("Unit %d cannot fire because it is less than %d%% efficient\n", fland.lnd_uid, LAND_MINFIREEFF);
197 resupply_commod(&fland, I_SHELL); /* Get more shells */
198 putland(fland.lnd_uid, &fland);
199 if (fland.lnd_item[I_SHELL] == 0) {
200 pr("%s -- not enough shells\n", prland(&fland));
203 } else if (attacker == targ_ship) {
204 if (!getship(item.ship.shp_uid, &fship))
206 if (item.ship.shp_own != player->cnum)
208 if (item.ship.shp_item[I_MILIT] < 1) {
209 pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
212 gun = item.ship.shp_item[I_GUN];
213 gun = min(gun, item.ship.shp_glim);
214 if (item.ship.shp_frnge == 0) {
215 pr("Ships %d cannot fire guns!\n", item.ship.shp_uid);
219 pr("Not enough guns on ship #%d\n", item.ship.shp_uid);
222 if (item.ship.shp_item[I_SHELL] == 0) {
223 pr("Not enough shells on ship #%d\n", item.ship.shp_uid);
226 if (item.ship.shp_effic < 60) {
227 pr("Ship #%d is crippled!\n", item.ship.shp_uid);
230 fshipno = fship.shp_uid;
231 } else if (attacker == targ_land) {
232 if (!getsect(item.sect.sct_x, item.sect.sct_y, &fsect))
234 if (item.sect.sct_own != player->cnum)
236 if (item.sect.sct_type != SCT_FORTR)
238 if (item.sect.sct_effic < ((u_char)FORTEFF)) {
239 pr("Fort not efficient enough to fire!\n");
242 if (item.sect.sct_item[I_GUN] == 0) {
243 pr("Not enough guns in sector %s!\n",
244 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
247 if (item.sect.sct_item[I_SHELL] == 0) {
248 pr("Not enough shells in sector %s!\n",
249 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
252 if (item.sect.sct_item[I_MILIT] < 5) {
253 pr("Not enough military in sector %s!\n",
254 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
257 pr("\nSector %s firing\n",
258 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
260 if ((ptr = getstarg(player->argp[3], "Firing at? ", buf)) == 0
263 if (player->aborted) {
264 pr("Fire aborted.\n");
268 (void)strcpy(vbuf, ptr);
273 if (target == targ_ship) {
274 vshipno = atoi(vbuf);
275 if (vshipno < 0 || !getship(vshipno, &vship) ||
277 pr("No such ship exists!\n");
280 target = (mchr[(int)vship.shp_type].m_flags & M_SUB) ?
281 targ_sub : targ_ship;
282 vict = vship.shp_own;
285 if (!getsect(x, y, &vsect)) {
286 pr("No such sector exists!\n");
290 if (!sarg_xy(vbuf, &x, &y) || !getsect(x, y, &vsect)) {
291 pr("No such sector exists!\n");
294 /* We check the sector type, but we only use it for damage, not
295 reporting. That way, you don't get extra information you wouldn't
296 normally get. Besides, what if they want to slam water? :) */
297 if (vsect.sct_type == SCT_SANCT || vsect.sct_type == SCT_WATER)
301 vict = vsect.sct_own;
305 if (attacker == targ_ship) {
306 if (fship.shp_own != player->cnum) {
307 pr("Not your ship!\n");
310 if (target == targ_sub || target == targ_ship) {
311 if (fship.shp_uid == vship.shp_uid) {
312 pr("You can't fire upon yourself!\n");
319 attacker = (mchr[fship.shp_type].m_flags & M_SUB) ?
320 targ_sub : targ_ship;
321 if (attacker == targ_sub){
322 pr("Subs may not fire normally.. use torpedo.\n");
326 attacker = targ_ship;
327 if ((mil = fship.shp_item[I_MILIT]) < 1) {
328 pr("Not enough military for firing crew.\n");
331 gun = fship.shp_item[I_GUN];
332 gun = min(gun, fship.shp_glim);
333 if (fship.shp_frnge == 0 || gun == 0) {
334 pr("Insufficient arms.\n");
337 shell = fship.shp_item[I_SHELL];
339 shell += supply_commod(fship.shp_own, fship.shp_x,
340 fship.shp_y, I_SHELL, 2 - shell);
345 if (fship.shp_effic < 60) {
346 pr("Ship #%d is crippled (%d%%)\n", fshipno,
350 range = techfact(fship.shp_tech,
351 (double)fship.shp_frnge / 2.0);
352 range2 = (double)roundrange(range);
353 pr("range is %.2f (%.2f)\n", range2, range);
354 if (target == targ_sub) {
355 if ((mchr[(int)fship.shp_type].m_flags & M_DCH) == 0) {
356 pr("A %s can't drop depth charges!\n",
357 mchr[(int)fship.shp_type].m_name);
361 pr("Not enough shells for depth charge!\n");
365 gun = min(gun, shell * 2);
366 gun = min(gun, mil / 2);
369 guneff = seagun(fship.shp_effic, shots);
371 shell -= ldround(((double)shots) / 2.0, 1);
372 fship.shp_item[I_SHELL] = shell;
373 if (opt_NOMOBCOST == 0)
374 fship.shp_mobil = max(fship.shp_mobil - 15, -100);
375 putship(fship.shp_uid, &fship);
376 } else if (attacker == targ_unit) {
377 if (fland.lnd_own != player->cnum) {
378 pr("Not your unit!\n");
382 if (target == targ_land) {
383 if (fland.lnd_x == vsect.sct_x
384 && fland.lnd_y == vsect.sct_y) {
385 pr("You can't fire upon yourself!\n");
393 if (fland.lnd_frg == 0) {
394 pr("Unit %d cannot fire!\n", fland.lnd_uid);
397 if (fland.lnd_item[I_SHELL] == 0) {
398 pr("%s -- not enough shells\n", prland(&fland));
402 shell = fland.lnd_item[I_SHELL];
404 range = techfact((int)fland.lnd_tech,
405 (double)fland.lnd_frg / 2.0);
406 range2 = (double)roundrange(range);
407 pr("range is %.2f (%.2f)\n", range2, range);
408 if (target == targ_sub) {
409 pr("A %s can't drop depth charges!\n",
410 lchr[(int)fland.lnd_type].l_name);
414 gun = fland.lnd_item[I_GUN];
416 pr("%s -- not enough guns\n", prland(&fland));
420 dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
421 fland.lnd_ammo, shell);
422 if (target == targ_ship) {
423 if (chance(((double)fland.lnd_acc) / 100.0))
424 dam = ldround(((double)dam / 2.0), 1);
427 resupply_commod(&fland, I_SHELL); /* Get more shells */
428 putland(fland.lnd_uid, &fland);
432 if (fsect.sct_own != player->cnum ||
433 fsect.sct_type != SCT_FORTR) {
434 pr("No fortress at %s\n", xyas(fsect.sct_x,
435 fsect.sct_y, player->cnum));
438 if (target == targ_land) {
439 if (fsect.sct_x == vsect.sct_x
440 && fsect.sct_y == vsect.sct_y) {
441 pr("You can't fire upon yourself!\n");
445 attacker = targ_land;
446 if ((gun = fsect.sct_item[I_GUN]) == 0) {
447 pr("Insufficient arms.\n");
450 shell = fsect.sct_item[I_SHELL];
452 shell += supply_commod(fsect.sct_own, fsect.sct_x,
453 fsect.sct_y, I_SHELL, 1);
458 if (fsect.sct_item[I_MILIT] < 5) {
459 pr("Not enough military for firing crew.\n");
462 if (target == targ_sub) {
463 pr("Target ship not sighted!\n");
468 range = tfactfire(player->cnum, 7.0);
469 if (fsect.sct_effic > 59)
471 range2 = (double)roundrange(range);
472 pr("range is %.2f (%.2f)\n", range2, range);
473 guneff = landgun((int)fsect.sct_effic, gun);
476 fsect.sct_item[I_SHELL] = shell;
479 trange = mapdist(x, y, fx, fy);
480 if (trange > range2) {
481 pr("Target out of range.\n");
486 pr("Target out of range. Thud.\n");
489 pr("Target ship out of range. Splash.\n");
498 fland.lnd_mission = 0;
499 putland(fland.lnd_uid, &fland);
502 fship.shp_mission = 0;
503 putship(fship.shp_uid, &fship);
508 if (target == targ_bogus) {
509 if (vsect.sct_type == SCT_SANCT) {
510 pr("%s is a %s!!\n", vbuf,
511 dchr[SCT_SANCT].d_name);
513 } else if (vsect.sct_type == SCT_WATER) {
514 pr("You must specify a ship in sector %s!\n",
522 if (!trechk(player->cnum, vict, SEAFIR))
526 if (!trechk(player->cnum, vict, SUBFIR))
531 if (!trechk(player->cnum, vict, LANFIR))
539 if (target == targ_land) {
540 natp = getnatp(player->cnum);
541 rel = getrel(natp, vict);
542 if ((rel != AT_WAR) && (player->cnum != vict) &&
543 (vict) && (vsect.sct_oldown != player->cnum)) {
544 pr("You're not at war with them!\n");
554 if (vship.shp_rflags & RET_DCHRGED)
555 retreat_ship(&vship, 'd');
560 prb = (double)(range2 ? (trange / range2) : 1.0);
569 pr("Wind deflects shell%s.\n", splur(shots));
570 /* dam = (int)((double)dam / 2.0);*/
573 (double)((double)(90 - (random() % 11)) /
583 nreport(player->cnum, N_SCT_SHELL, vict, 1);
584 if (vict && vict != player->cnum)
586 "Country #%d shelled sector %s for %d damage.\n",
587 player->cnum, xyas(x, y, vict), dam);
588 pr("Shell%s hit sector %s for %d damage.\n",
589 splur(shots), xyas(x, y, player->cnum), dam);
590 /* Ok, it wasn't a bogus target, so do damage. */
591 if (target != targ_bogus)
592 sectdamage(&vsect, dam, 0);
595 nreport(player->cnum, N_SHP_SHELL, vict, 1);
598 if ((target != targ_sub) ||
599 ((vship.shp_rflags & RET_DCHRGED) == 0))
600 check_retreat_and_do_shipdamage(&vship, dam);
602 shipdamage(&vship, dam);
605 "Country #%d shelled %s in %s for %d damage.\n",
606 player->cnum, prship(&vship),
607 xyas(vship.shp_x, vship.shp_y, vict), dam);
609 pr("Shell%s hit %s in %s for %d damage.\n",
610 splur(shots), prsub(&vship),
611 xyas(vship.shp_x, vship.shp_y, player->cnum), dam);
613 if (vship.shp_effic < SHIP_MINEFF)
614 pr("%s sunk!\n", prsub(&vship));
618 /* Ok, now, check if we had a bogus target. If so,
619 just continue on, since there is no defender. */
620 if (target == targ_bogus)
622 if (attacker == targ_unit) {
623 attacker = targ_land;
624 getsect(fland.lnd_x, fland.lnd_y, &fsect);
627 defend(&fired, &defended, target, attacker, &vsect, &fsect,
628 &vship, &fship, fx, fy, &ndefending);
634 putship(vship.shp_uid, &vship);
637 if ((totaldefdam == 0) && (target == targ_ship))
638 if (vship.shp_rflags & RET_INJURED)
639 retreat_ship(&vship, 'h');
645 if ((target == targ_ship) || (target == targ_sub)) {
646 if (fship.shp_effic > SHIP_MINEFF) {
647 shp_missdef(&fship, vict);
650 putship(fship.shp_uid, &fship);
657 odds = ((double)ndefending) / ((double)nfiring);
660 do_defdam(&fired, odds);
665 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target,
666 enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect,
667 struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
671 int vict, nfiring = 0;
675 if (attacker == targ_land)
676 aown = fsect->sct_own;
678 aown = fship->shp_own;
680 if (target == targ_land)
681 vict = vsect->sct_own;
683 vict = vship->shp_own;
686 (dam = quiet_bigdef(attacker, dl, vict, aown, fx, fy, &nfiring))) {
689 fp = (struct flist *)malloc(sizeof(struct flist));
690 memset(fp, 0, sizeof(struct flist));
695 fp->x = fsect->sct_x;
696 fp->y = fsect->sct_y;
697 fp->type = targ_land;
700 fp->type = targ_ship;
701 fp->uid = fship->shp_uid;
704 emp_insque(&fp->queue, al);
711 do_defdam(struct emp_qelem *list, double odds)
714 int dam, vict, first = 1;
718 struct emp_qelem *qp, *next;
720 for (qp = list->q_forw; qp != list; qp = next) {
722 fp = (struct flist *)qp;
723 if (fp->type == targ_ship) {
724 if (!getship(fp->uid, &ship) || !ship.shp_own)
729 pr("\nDefenders fire back!\n");
732 dam = (odds * (double)fp->defdam);
734 if (fp->type == targ_ship) {
736 pr("Return fire hit %s in %s for %d damage.\n",
738 xyas(ship.shp_x, ship.shp_y, player->cnum), dam);
741 "Return fire hit %s in %s for %d damage.\n",
742 prsub(&ship), xyas(ship.shp_x, ship.shp_y, vict), dam);
743 shipdamage(&ship, dam);
744 putship(ship.shp_uid, &ship);
746 getsect(fp->x, fp->y, §);
748 pr("Return fire hit sector %s for %d damage.\n",
749 xyas(fp->x, fp->y, player->cnum), dam);
750 sectdamage(§, dam, 0);
753 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
754 xyas(fp->x, fp->y, vict), dam);
756 emp_remque(&fp->queue);
762 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
763 coord ax, coord ay, int *nfiring)
766 double range, erange, hitchance;
770 int dam, dam2, rel, rel2;
772 struct sctstr firing;
780 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
781 while (nxtitem(&ni, &ship)) {
782 if (ship.shp_own == 0)
785 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
786 (attacker == targ_land))
789 rel = getrel(getnatp(ship.shp_own), own);
790 rel2 = getrel(getnatp(ship.shp_own), aown);
791 if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
793 /* Don't shoot yourself */
794 if (ship.shp_own == aown)
796 if (ship.shp_effic < 60)
799 gun = ship.shp_item[I_GUN];
800 shell = ship.shp_item[I_SHELL];
802 if (ship.shp_item[I_MILIT] < 1)
805 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
806 if (shell < SHP_TORP_SHELLS)
807 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
808 I_SHELL, SHP_TORP_SHELLS - shell);
809 if (shell < SHP_TORP_SHELLS)
814 if (ship.shp_mobil <= 0)
817 erange = ship.shp_effic *
818 techfact(ship.shp_tech, ((double)ship.shp_frnge))
820 erange = (double)roundrange(erange);
821 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
824 if (!line_of_sight((s_char **)0, ship.shp_x, ship.shp_y, ax, ay))
828 fp = (struct flist *)malloc(sizeof(struct flist));
829 memset(fp, 0, sizeof(struct flist));
830 fp->type = targ_ship;
831 fp->uid = ship.shp_uid;
832 add_to_fired_queue(&fp->queue, list);
834 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
836 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
837 if (!chance(hitchance))
840 dam += TORP_DAMAGE();
842 range = techfact(ship.shp_tech,
843 ship.shp_frnge * ship.shp_effic / 200.0);
844 range = (double)roundrange(range);
845 if (range < ni.curdist)
847 /* must have gun, shell, and milit to fire */
849 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
851 /* only need 1 shell, so don't check that */
854 nshot = min(gun, ship.shp_item[I_MILIT]);
855 nshot = min(nshot, ship.shp_glim);
859 fp = (struct flist *)malloc(sizeof(struct flist));
860 memset(fp, 0, sizeof(struct flist));
861 fp->type = targ_ship;
862 fp->uid = ship.shp_uid;
863 add_to_fired_queue(&fp->queue, list);
864 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
865 dam += seagun(ship.shp_effic, nshot);
868 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
869 while (nxtitem(&ni, &land)) {
870 if (land.lnd_own == 0)
872 if (land.lnd_effic < LAND_MINFIREEFF)
874 /* Can't fire if on a ship */
875 if (land.lnd_ship >= 0)
877 if (land.lnd_land >= 0)
879 /* Gotta have military */
880 if (lnd_getmil(&land) < 1)
882 /* Don't shoot yourself */
883 if (land.lnd_own == aown)
886 rel = getrel(getnatp(land.lnd_own), own);
887 rel2 = getrel(getnatp(land.lnd_own), aown);
889 if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
893 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
894 range = (double)roundrange(range);
895 if (range < ni.curdist)
899 if (!has_supply(&land))
902 gun = land.lnd_item[I_GUN];
903 shell = land.lnd_item[I_SHELL];
905 if (land.lnd_item[I_MILIT] == 0 || shell == 0 || gun == 0)
908 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, gun,
909 land.lnd_ammo, shell);
912 fp = (struct flist *)malloc(sizeof(struct flist));
913 memset(fp, 0, sizeof(struct flist));
914 fp->type = targ_unit;
915 fp->uid = land.lnd_uid;
916 add_to_fired_queue(&fp->queue, list);
918 putland(land.lnd_uid, &land);
919 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
924 * Determine if any nearby gun-equipped sectors are within
925 * range and able to fire at an attacker. Firing sectors
926 * need to have guns, shells, and military. Sector being
927 * attacked is x,y -- attacker is at ax,ay.
930 if (!opt_NO_FORT_FIRE) {
931 snxtsct_dist(&ns, ax, ay, 8);
932 while (nxtsct(&ns, &firing)) {
934 if (firing.sct_type != SCT_FORTR)
936 if (firing.sct_own == 0)
938 rel = getrel(getnatp(firing.sct_own), own);
939 rel2 = getrel(getnatp(firing.sct_own), aown);
941 if ((firing.sct_own != own) &&
942 ((rel != ALLIED) || (rel2 != AT_WAR)))
944 /* Don't shoot yourself */
945 if (firing.sct_own == aown)
947 tech = tfactfire(firing.sct_own, 1.0);
949 if (firing.sct_effic > 59) /* fort bonus */
951 range = (double)roundrange(range);
952 if (range < ns.curdist)
955 gun = firing.sct_item[I_GUN];
956 shell = firing.sct_item[I_SHELL];
959 shell += supply_commod(firing.sct_own,
960 firing.sct_x, firing.sct_y,
962 if (gun == 0 || firing.sct_item[I_MILIT] < 5 || shell == 0)
965 fp = (struct flist *)malloc(sizeof(struct flist));
966 memset(fp, 0, sizeof(struct flist));
967 fp->x = firing.sct_x;
968 fp->y = firing.sct_y;
969 fp->type = targ_land;
970 add_to_fired_queue(&fp->queue, list);
971 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
974 dam += landgun((int)firing.sct_effic, gun);
978 return ((*nfiring) == 0 ? 0 : (dam / (*nfiring)));
982 use_ammo(struct emp_qelem *list)
984 struct emp_qelem *qp, *next;
994 /* use 1 shell from everyone */
995 for (qp = list->q_forw; qp != list; qp = next) {
997 fp = (struct flist *)qp;
998 if (fp->type == targ_ship) {
999 getship(fp->uid, &ship);
1000 item = ship.shp_item;
1001 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
1002 shell = item[I_SHELL];
1003 shell -= SHP_TORP_SHELLS - 1;
1006 item[I_SHELL] = shell;
1007 putship(ship.shp_uid, &ship);
1008 mcp = &mchr[(int)ship.shp_type];
1009 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
1010 mobcost = (480.0 / (mobcost +
1011 techfact(ship.shp_tech, mobcost)));
1012 /* mob cost = 1/2 a sect's mob */
1014 ship.shp_mobil -= mobcost;
1016 } else if (fp->type == targ_land) {
1017 getsect(fp->x, fp->y, §);
1018 item = sect.sct_item;
1020 getland(fp->uid, &land);
1021 item = land.lnd_item;
1023 shell = item[I_SHELL];
1027 item[I_SHELL] = shell;
1028 if (fp->type == targ_ship)
1029 putship(ship.shp_uid, &ship);
1030 else if (fp->type == targ_land)
1033 putland(land.lnd_uid, &land);
1035 emp_remque(&fp->queue);
1042 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1044 struct emp_qelem *qp;
1045 struct flist *fp, *ep;
1048 ep = (struct flist *)elem;
1050 /* Don't put them on the list if they're already there */
1051 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1052 fp = (struct flist *)qp;
1053 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1055 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1061 emp_insque(elem, list);