2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2005, 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 *);
89 static int ef_with_guns[] = { EF_SECTOR, EF_SHIP, EF_LAND, EF_BAD };
114 enum targ_type target, attacker, orig_attacker;
117 struct nstr_item nbst;
123 struct emp_qelem fired, defended;
128 emp_initque(&defended);
129 if (!(p = getstarg(player->argp[1],
130 "Firing from ship(s), sect(s), or land unit(s)? ",
133 type = ef_byname_from(p, ef_with_guns);
134 if (type == EF_SECTOR) {
135 if (opt_NO_FORT_FIRE) {
136 pr("Fort firing is disabled.\n");
139 orig_attacker = attacker = targ_land;
141 } else if (type == EF_SHIP) {
142 orig_attacker = attacker = targ_ship;
143 } else if (type == EF_LAND) {
144 orig_attacker = attacker = targ_unit;
146 pr("Ships, land units or sectors only!\n");
149 if ((ptr = getstarg(player->argp[2], "Firing from? ", buf)) == 0
153 if (!snxtitem(&nbst, type, ptr))
156 if (player->aborted) {
157 pr("Fire aborted.\n");
160 while (nxtitem(&nbst, &item)) {
161 attacker = orig_attacker;
162 if (attacker == targ_unit) {
163 if (!getland(item.land.lnd_uid, &fland))
165 if (!getsect(item.land.lnd_x, item.land.lnd_y, &fsect))
167 if (item.land.lnd_own != player->cnum)
170 if (fland.lnd_frg == 0) {
171 pr("Unit %d cannot fire!\n", fland.lnd_uid);
174 if (lnd_getmil(&fland) < 1) {
175 pr("Unit %d cannot fire because it has no military!\n",
179 if (fland.lnd_ship >= 0) {
180 pr("Unit %d cannot fire because it is on a ship!\n",
184 if (fland.lnd_land >= 0) {
185 pr("Unit %d cannot fire because it is on a land unit!\n",
189 if (fland.lnd_effic < LAND_MINFIREEFF) {
190 pr("Unit %d cannot fire because it is less than %d%% efficient\n", fland.lnd_uid, LAND_MINFIREEFF);
193 resupply_commod(&fland, I_SHELL); /* Get more shells */
194 putland(fland.lnd_uid, &fland);
195 if (fland.lnd_item[I_SHELL] == 0) {
196 pr("%s -- not enough shells\n", prland(&fland));
199 } else if (attacker == targ_ship) {
200 if (!getship(item.ship.shp_uid, &fship))
202 if (item.ship.shp_own != player->cnum)
204 if (item.ship.shp_item[I_MILIT] < 1) {
205 pr("Not enough mil on ship #%d\n", item.ship.shp_uid);
208 gun = item.ship.shp_item[I_GUN];
209 gun = min(gun, item.ship.shp_glim);
210 if (item.ship.shp_frnge == 0) {
211 pr("Ships %d cannot fire guns!\n", item.ship.shp_uid);
215 pr("Not enough guns on ship #%d\n", item.ship.shp_uid);
218 if (item.ship.shp_item[I_SHELL] == 0) {
219 pr("Not enough shells on ship #%d\n", item.ship.shp_uid);
222 if (item.ship.shp_effic < 60) {
223 pr("Ship #%d is crippled!\n", item.ship.shp_uid);
226 fshipno = fship.shp_uid;
227 } else if (attacker == targ_land) {
228 if (!getsect(item.sect.sct_x, item.sect.sct_y, &fsect))
230 if (item.sect.sct_own != player->cnum)
232 if (item.sect.sct_type != SCT_FORTR)
234 if (item.sect.sct_effic < ((u_char)FORTEFF)) {
235 pr("Fort not efficient enough to fire!\n");
238 if (item.sect.sct_item[I_GUN] == 0) {
239 pr("Not enough guns in sector %s!\n",
240 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
243 if (item.sect.sct_item[I_SHELL] == 0) {
244 pr("Not enough shells in sector %s!\n",
245 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
248 if (item.sect.sct_item[I_MILIT] < 5) {
249 pr("Not enough military in sector %s!\n",
250 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
253 pr("\nSector %s firing\n",
254 xyas(item.sect.sct_x, item.sect.sct_y, player->cnum));
256 if ((ptr = getstarg(player->argp[3], "Firing at? ", buf)) == 0
259 if (player->aborted) {
260 pr("Fire aborted.\n");
264 (void)strcpy(vbuf, ptr);
269 if (target == targ_ship) {
270 vshipno = atoi(vbuf);
271 if (vshipno < 0 || !getship(vshipno, &vship) ||
273 pr("No such ship exists!\n");
276 target = (mchr[(int)vship.shp_type].m_flags & M_SUB) ?
277 targ_sub : targ_ship;
278 vict = vship.shp_own;
281 if (!getsect(x, y, &vsect)) {
282 pr("No such sector exists!\n");
286 if (!sarg_xy(vbuf, &x, &y) || !getsect(x, y, &vsect)) {
287 pr("No such sector exists!\n");
290 /* We check the sector type, but we only use it for damage, not
291 reporting. That way, you don't get extra information you wouldn't
292 normally get. Besides, what if they want to slam water? :) */
293 if (vsect.sct_type == SCT_SANCT || vsect.sct_type == SCT_WATER)
297 vict = vsect.sct_own;
301 if (attacker == targ_ship) {
302 if (fship.shp_own != player->cnum) {
303 pr("Not your ship!\n");
306 if (target == targ_sub || target == targ_ship) {
307 if (fship.shp_uid == vship.shp_uid) {
308 pr("You can't fire upon yourself!\n");
315 attacker = (mchr[fship.shp_type].m_flags & M_SUB) ?
316 targ_sub : targ_ship;
317 if (attacker == targ_sub){
318 pr("Subs may not fire normally.. use torpedo.\n");
322 attacker = targ_ship;
323 if ((mil = fship.shp_item[I_MILIT]) < 1) {
324 pr("Not enough military for firing crew.\n");
327 gun = fship.shp_item[I_GUN];
328 gun = min(gun, fship.shp_glim);
329 if (fship.shp_frnge == 0 || gun == 0) {
330 pr("Insufficient arms.\n");
333 shell = fship.shp_item[I_SHELL];
335 shell += supply_commod(fship.shp_own, fship.shp_x,
336 fship.shp_y, I_SHELL, 2 - shell);
341 if (fship.shp_effic < 60) {
342 pr("Ship #%d is crippled (%d%%)\n", fshipno,
346 range = techfact(fship.shp_tech,
347 (double)fship.shp_frnge / 2.0);
348 range2 = (double)roundrange(range);
349 pr("range is %.2f (%.2f)\n", range2, range);
350 if (target == targ_sub) {
351 if ((mchr[(int)fship.shp_type].m_flags & M_DCH) == 0) {
352 /* Don't tell it's a sub */
354 } else if (shell < 2) {
355 pr("Not enough shells for depth charge!\n");
359 gun = min(gun, shell * 2);
360 gun = min(gun, mil / 2);
363 guneff = seagun(fship.shp_effic, shots);
365 shell -= ldround(((double)shots) / 2.0, 1);
366 fship.shp_item[I_SHELL] = shell;
367 if (opt_NOMOBCOST == 0)
368 fship.shp_mobil = max(fship.shp_mobil - 15, -100);
369 putship(fship.shp_uid, &fship);
370 } else if (attacker == targ_unit) {
371 if (fland.lnd_own != player->cnum) {
372 pr("Not your unit!\n");
376 if (target == targ_land) {
377 if (fland.lnd_x == vsect.sct_x
378 && fland.lnd_y == vsect.sct_y) {
379 pr("You can't fire upon yourself!\n");
387 if (fland.lnd_frg == 0) {
388 pr("Unit %d cannot fire!\n", fland.lnd_uid);
391 if (fland.lnd_item[I_SHELL] == 0) {
392 pr("%s -- not enough shells\n", prland(&fland));
396 shell = fland.lnd_item[I_SHELL];
398 range = techfact((int)fland.lnd_tech,
399 (double)fland.lnd_frg / 2.0);
400 range2 = (double)roundrange(range);
401 pr("range is %.2f (%.2f)\n", range2, range);
402 if (target == targ_sub) {
403 /* Don't tell it's a sub */
407 gun = fland.lnd_item[I_GUN];
409 pr("%s -- not enough guns\n", prland(&fland));
413 dam = (int)landunitgun(fland.lnd_effic, fland.lnd_dam, gun,
414 fland.lnd_ammo, shell);
415 if (target == targ_ship) {
416 if (chance(((double)fland.lnd_acc) / 100.0))
417 dam = ldround(((double)dam / 2.0), 1);
420 resupply_commod(&fland, I_SHELL); /* Get more shells */
421 putland(fland.lnd_uid, &fland);
425 if (fsect.sct_own != player->cnum ||
426 fsect.sct_type != SCT_FORTR) {
427 pr("No fortress at %s\n", xyas(fsect.sct_x,
428 fsect.sct_y, player->cnum));
431 if (target == targ_land) {
432 if (fsect.sct_x == vsect.sct_x
433 && fsect.sct_y == vsect.sct_y) {
434 pr("You can't fire upon yourself!\n");
438 attacker = targ_land;
439 if ((gun = fsect.sct_item[I_GUN]) == 0) {
440 pr("Insufficient arms.\n");
443 shell = fsect.sct_item[I_SHELL];
445 shell += supply_commod(fsect.sct_own, fsect.sct_x,
446 fsect.sct_y, I_SHELL, 1);
451 if (fsect.sct_item[I_MILIT] < 5) {
452 pr("Not enough military for firing crew.\n");
457 range = tfactfire(player->cnum, 7.0);
458 if (fsect.sct_effic > 59)
460 range2 = (double)roundrange(range);
461 pr("range is %.2f (%.2f)\n", range2, range);
462 if (target == targ_sub) {
463 /* Don't tell it's a sub */
466 guneff = landgun((int)fsect.sct_effic, gun);
469 fsect.sct_item[I_SHELL] = shell;
472 trange = mapdist(x, y, fx, fy);
473 if (trange > range2) {
474 pr("Target out of range.\n");
479 pr("Target out of range. Thud.\n");
482 pr("Target ship out of range. Splash.\n");
491 fland.lnd_mission = 0;
492 putland(fland.lnd_uid, &fland);
495 fship.shp_mission = 0;
496 putship(fship.shp_uid, &fship);
501 if (target == targ_bogus) {
502 if (vsect.sct_type == SCT_SANCT) {
503 pr("%s is a %s!!\n", vbuf,
504 dchr[SCT_SANCT].d_name);
506 } else if (vsect.sct_type == SCT_WATER) {
507 pr("You must specify a ship in sector %s!\n",
515 if (!trechk(player->cnum, vict, SEAFIR))
519 if (!trechk(player->cnum, vict, SUBFIR))
524 if (!trechk(player->cnum, vict, LANFIR))
532 if (target == targ_land) {
533 natp = getnatp(player->cnum);
534 rel = getrel(natp, vict);
535 if ((rel != AT_WAR) && (player->cnum != vict) &&
536 (vict) && (vsect.sct_oldown != player->cnum)) {
537 pr("You're not at war with them!\n");
547 if (vship.shp_rflags & RET_DCHRGED)
548 retreat_ship(&vship, 'd');
553 prb = (double)(range2 ? (trange / range2) : 1.0);
556 pr("Wind deflects shell%s.\n", splur(shots));
557 /* dam = (int)((double)dam / 2.0);*/
560 (double)((double)(90 - (random() % 11)) /
570 nreport(player->cnum, N_SCT_SHELL, vict, 1);
571 if (vict && vict != player->cnum)
573 "Country #%d shelled sector %s for %d damage.\n",
574 player->cnum, xyas(x, y, vict), dam);
575 pr("Shell%s hit sector %s for %d damage.\n",
576 splur(shots), xyas(x, y, player->cnum), dam);
577 /* Ok, it wasn't a bogus target, so do damage. */
578 if (target != targ_bogus)
579 sectdamage(&vsect, dam, 0);
582 nreport(player->cnum, N_SHP_SHELL, vict, 1);
585 if ((target != targ_sub) ||
586 ((vship.shp_rflags & RET_DCHRGED) == 0))
587 check_retreat_and_do_shipdamage(&vship, dam);
589 shipdamage(&vship, dam);
592 "Country #%d shelled %s in %s for %d damage.\n",
593 player->cnum, prship(&vship),
594 xyas(vship.shp_x, vship.shp_y, vict), dam);
596 pr("Shell%s hit %s in %s for %d damage.\n",
597 splur(shots), prsub(&vship),
598 xyas(vship.shp_x, vship.shp_y, player->cnum), dam);
600 if (vship.shp_effic < SHIP_MINEFF)
601 pr("%s sunk!\n", prsub(&vship));
605 /* Ok, now, check if we had a bogus target. If so,
606 just continue on, since there is no defender. */
607 if (target == targ_bogus)
609 if (attacker == targ_unit) {
610 attacker = targ_land;
611 getsect(fland.lnd_x, fland.lnd_y, &fsect);
614 defend(&fired, &defended, target, attacker, &vsect, &fsect,
615 &vship, &fship, fx, fy, &ndefending);
621 putship(vship.shp_uid, &vship);
624 if ((totaldefdam == 0) && (target == targ_ship))
625 if (vship.shp_rflags & RET_INJURED)
626 retreat_ship(&vship, 'h');
632 if ((target == targ_ship) || (target == targ_sub)) {
633 if (fship.shp_effic > SHIP_MINEFF) {
634 shp_missdef(&fship, vict);
637 putship(fship.shp_uid, &fship);
644 odds = ((double)ndefending) / ((double)nfiring);
647 do_defdam(&fired, odds);
652 defend(struct emp_qelem *al, struct emp_qelem *dl, enum targ_type target,
653 enum targ_type attacker, struct sctstr *vsect, struct sctstr *fsect,
654 struct shpstr *vship, struct shpstr *fship, int fx, int fy, int *nd)
658 int vict, nfiring = 0;
662 if (attacker == targ_land)
663 aown = fsect->sct_own;
665 aown = fship->shp_own;
667 if (target == targ_land)
668 vict = vsect->sct_own;
670 vict = vship->shp_own;
673 (dam = quiet_bigdef(attacker, dl, vict, aown, fx, fy, &nfiring))) {
676 fp = malloc(sizeof(struct flist));
677 memset(fp, 0, sizeof(struct flist));
682 fp->x = fsect->sct_x;
683 fp->y = fsect->sct_y;
684 fp->type = targ_land;
687 fp->type = targ_ship;
688 fp->uid = fship->shp_uid;
691 emp_insque(&fp->queue, al);
698 do_defdam(struct emp_qelem *list, double odds)
701 int dam, vict, first = 1;
705 struct emp_qelem *qp, *next;
707 for (qp = list->q_forw; qp != list; qp = next) {
709 fp = (struct flist *)qp;
710 if (fp->type == targ_ship) {
711 if (!getship(fp->uid, &ship) || !ship.shp_own)
716 pr("\nDefenders fire back!\n");
719 dam = (odds * (double)fp->defdam);
721 if (fp->type == targ_ship) {
723 pr("Return fire hit %s in %s for %d damage.\n",
725 xyas(ship.shp_x, ship.shp_y, player->cnum), dam);
728 "Return fire hit %s in %s for %d damage.\n",
729 prsub(&ship), xyas(ship.shp_x, ship.shp_y, vict), dam);
730 shipdamage(&ship, dam);
731 putship(ship.shp_uid, &ship);
733 getsect(fp->x, fp->y, §);
735 pr("Return fire hit sector %s for %d damage.\n",
736 xyas(fp->x, fp->y, player->cnum), dam);
737 sectdamage(§, dam, 0);
740 wu(0, vict, "Return fire hit sector %s for %d damage.\n",
741 xyas(fp->x, fp->y, vict), dam);
743 emp_remque(&fp->queue);
749 quiet_bigdef(int attacker, struct emp_qelem *list, natid own, natid aown,
750 coord ax, coord ay, int *nfiring)
753 double range, erange, hitchance;
757 int dam, dam2, rel, rel2;
759 struct sctstr firing;
767 snxtitem_dist(&ni, EF_SHIP, ax, ay, 8);
768 while (nxtitem(&ni, &ship)) {
769 if (ship.shp_own == 0)
772 if ((mchr[(int)ship.shp_type].m_flags & M_SUB) &&
773 (attacker == targ_land))
776 rel = getrel(getnatp(ship.shp_own), own);
777 rel2 = getrel(getnatp(ship.shp_own), aown);
778 if ((ship.shp_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
780 /* Don't shoot yourself */
781 if (ship.shp_own == aown)
783 if (ship.shp_effic < 60)
786 gun = ship.shp_item[I_GUN];
787 shell = ship.shp_item[I_SHELL];
789 if (ship.shp_item[I_MILIT] < 1)
792 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
793 if (shell < SHP_TORP_SHELLS)
794 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
795 I_SHELL, SHP_TORP_SHELLS - shell);
796 if (shell < SHP_TORP_SHELLS)
801 if (ship.shp_mobil <= 0)
804 erange = ship.shp_effic *
805 techfact(ship.shp_tech, ((double)ship.shp_frnge))
807 erange = (double)roundrange(erange);
808 range = mapdist(ship.shp_x, ship.shp_y, ax, ay);
811 if (!line_of_sight((s_char **)0, ship.shp_x, ship.shp_y, ax, ay))
815 fp = malloc(sizeof(struct flist));
816 memset(fp, 0, sizeof(struct flist));
817 fp->type = targ_ship;
818 fp->uid = ship.shp_uid;
819 add_to_fired_queue(&fp->queue, list);
821 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
823 hitchance = DTORP_HITCHANCE(range, ship.shp_visib);
824 if (!chance(hitchance))
827 dam += TORP_DAMAGE();
829 range = techfact(ship.shp_tech,
830 ship.shp_frnge * ship.shp_effic / 200.0);
831 range = (double)roundrange(range);
832 if (range < ni.curdist)
834 /* must have gun, shell, and milit to fire */
836 shell += supply_commod(ship.shp_own, ship.shp_x, ship.shp_y,
838 /* only need 1 shell, so don't check that */
841 nshot = min(gun, ship.shp_item[I_MILIT]);
842 nshot = min(nshot, ship.shp_glim);
846 fp = malloc(sizeof(struct flist));
847 memset(fp, 0, sizeof(struct flist));
848 fp->type = targ_ship;
849 fp->uid = ship.shp_uid;
850 add_to_fired_queue(&fp->queue, list);
851 nreport(ship.shp_own, N_FIRE_BACK, player->cnum, 1);
852 dam += seagun(ship.shp_effic, nshot);
855 snxtitem_dist(&ni, EF_LAND, ax, ay, 8);
856 while (nxtitem(&ni, &land)) {
857 if (land.lnd_own == 0)
859 if (land.lnd_effic < LAND_MINFIREEFF)
861 /* Can't fire if on a ship */
862 if (land.lnd_ship >= 0)
864 if (land.lnd_land >= 0)
866 /* Gotta have military */
867 if (lnd_getmil(&land) < 1)
869 /* Don't shoot yourself */
870 if (land.lnd_own == aown)
873 rel = getrel(getnatp(land.lnd_own), own);
874 rel2 = getrel(getnatp(land.lnd_own), aown);
876 if ((land.lnd_own != own) && ((rel != ALLIED) || (rel2 != AT_WAR)))
880 range = techfact((int)land.lnd_tech, (double)land.lnd_frg / 2.0);
881 range = (double)roundrange(range);
882 if (range < ni.curdist)
886 if (!has_supply(&land))
889 gun = land.lnd_item[I_GUN];
890 shell = land.lnd_item[I_SHELL];
892 if (land.lnd_item[I_MILIT] == 0 || shell == 0 || gun == 0)
895 dam2 = (int)landunitgun(land.lnd_effic, land.lnd_dam, gun,
896 land.lnd_ammo, shell);
899 fp = malloc(sizeof(struct flist));
900 memset(fp, 0, sizeof(struct flist));
901 fp->type = targ_unit;
902 fp->uid = land.lnd_uid;
903 add_to_fired_queue(&fp->queue, list);
905 putland(land.lnd_uid, &land);
906 nreport(land.lnd_own, N_FIRE_BACK, player->cnum, 1);
911 * Determine if any nearby gun-equipped sectors are within
912 * range and able to fire at an attacker. Firing sectors
913 * need to have guns, shells, and military. Sector being
914 * attacked is x,y -- attacker is at ax,ay.
917 if (!opt_NO_FORT_FIRE) {
918 snxtsct_dist(&ns, ax, ay, 8);
919 while (nxtsct(&ns, &firing)) {
921 if (firing.sct_type != SCT_FORTR)
923 if (firing.sct_own == 0)
925 rel = getrel(getnatp(firing.sct_own), own);
926 rel2 = getrel(getnatp(firing.sct_own), aown);
928 if ((firing.sct_own != own) &&
929 ((rel != ALLIED) || (rel2 != AT_WAR)))
931 /* Don't shoot yourself */
932 if (firing.sct_own == aown)
934 tech = tfactfire(firing.sct_own, 1.0);
936 if (firing.sct_effic > 59) /* fort bonus */
938 range = (double)roundrange(range);
939 if (range < ns.curdist)
942 gun = firing.sct_item[I_GUN];
943 shell = firing.sct_item[I_SHELL];
946 shell += supply_commod(firing.sct_own,
947 firing.sct_x, firing.sct_y,
949 if (gun == 0 || firing.sct_item[I_MILIT] < 5 || shell == 0)
952 fp = malloc(sizeof(struct flist));
953 memset(fp, 0, sizeof(struct flist));
954 fp->x = firing.sct_x;
955 fp->y = firing.sct_y;
956 fp->type = targ_land;
957 add_to_fired_queue(&fp->queue, list);
958 nreport(firing.sct_own, N_FIRE_BACK, player->cnum, 1);
961 dam += landgun((int)firing.sct_effic, gun);
965 return *nfiring == 0 ? 0 : dam / *nfiring;
969 use_ammo(struct emp_qelem *list)
971 struct emp_qelem *qp, *next;
981 /* use 1 shell from everyone */
982 for (qp = list->q_forw; qp != list; qp = next) {
984 fp = (struct flist *)qp;
985 if (fp->type == targ_ship) {
986 getship(fp->uid, &ship);
987 item = ship.shp_item;
988 if (mchr[(int)ship.shp_type].m_flags & M_SUB) {
989 shell = item[I_SHELL];
990 shell -= SHP_TORP_SHELLS - 1;
993 item[I_SHELL] = shell;
994 putship(ship.shp_uid, &ship);
995 mcp = &mchr[(int)ship.shp_type];
996 mobcost = ship.shp_effic * 0.01 * ship.shp_speed;
997 mobcost = (480.0 / (mobcost +
998 techfact(ship.shp_tech, mobcost)));
999 /* mob cost = 1/2 a sect's mob */
1001 ship.shp_mobil -= mobcost;
1003 } else if (fp->type == targ_land) {
1004 getsect(fp->x, fp->y, §);
1005 item = sect.sct_item;
1007 getland(fp->uid, &land);
1008 item = land.lnd_item;
1010 shell = item[I_SHELL];
1014 item[I_SHELL] = shell;
1015 if (fp->type == targ_ship)
1016 putship(ship.shp_uid, &ship);
1017 else if (fp->type == targ_land)
1020 putland(land.lnd_uid, &land);
1022 emp_remque(&fp->queue);
1029 add_to_fired_queue(struct emp_qelem *elem, struct emp_qelem *list)
1031 struct emp_qelem *qp;
1032 struct flist *fp, *ep;
1035 ep = (struct flist *)elem;
1037 /* Don't put them on the list if they're already there */
1038 for (qp = list->q_forw; qp != list; qp = qp->q_forw) {
1039 fp = (struct flist *)qp;
1040 if ((fp->type == targ_ship) && (fp->uid == ep->uid))
1042 if ((fp->type != targ_ship) && (fp->x == ep->x) &&
1048 emp_insque(elem, list);