Home | History | Annotate | Line # | Download | only in sail
pl_3.c revision 1.3
      1 /*	$NetBSD: pl_3.c,v 1.3 1995/04/22 10:37:09 cgd Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1983, 1993
      5  *	The Regents of the University of California.  All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *	This product includes software developed by the University of
     18  *	California, Berkeley and its contributors.
     19  * 4. Neither the name of the University nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #ifndef lint
     37 #if 0
     38 static char sccsid[] = "@(#)pl_3.c	8.1 (Berkeley) 5/31/93";
     39 #else
     40 static char rcsid[] = "$NetBSD: pl_3.c,v 1.3 1995/04/22 10:37:09 cgd Exp $";
     41 #endif
     42 #endif /* not lint */
     43 
     44 #include "player.h"
     45 
     46 acceptcombat()
     47 {
     48 	int men = 0;
     49 	int target, temp;
     50 	int n, r;
     51 	int index, rakehim, sternrake;
     52 	int hhits = 0, ghits = 0, rhits = 0, chits = 0;
     53 	int crew[3];
     54 	int load;
     55 	int guns, car, ready, shootat, hit;
     56 	int roll;
     57 	struct ship *closest;
     58 
     59 	crew[0] = mc->crew1;
     60 	crew[1] = mc->crew2;
     61 	crew[2] = mc->crew3;
     62 	for (n = 0; n < 3; n++) {
     63 		if (mf->OBP[n].turnsent)
     64 			men += mf->OBP[n].mensent;
     65 	}
     66 	for (n = 0; n < 3; n++) {
     67 		if (mf->DBP[n].turnsent)
     68 			men += mf->DBP[n].mensent;
     69 	}
     70 	if (men) {
     71 		crew[0] = men/100 ? 0 : crew[0] != 0;
     72 		crew[1] = (men%100)/10 ? 0 : crew[1] != 0;
     73 		crew[2] = men%10 ? 0 : crew[2] != 0;
     74 	}
     75 	for (r = 0; r < 2; r++) {
     76 		if (r) {
     77 			ready = mf->readyR;
     78 			load = mf->loadR;
     79 			guns = mc->gunR;
     80 			car = mc->carR;
     81 		} else {
     82 			ready = mf->readyL;
     83 			load = mf->loadL;
     84 			guns = mc->gunL;
     85 			car = mc->carL;
     86 		}
     87 		if (!guns && !car || load == L_EMPTY || (ready & R_LOADED) == 0)
     88 			goto cant;
     89 		if (mf->struck || !crew[2])
     90 			goto cant;
     91 		closest = closestenemy(ms, (r ? 'r' : 'l'), 1);
     92 		if (closest == 0)
     93 			goto cant;
     94 		if (closest->file->struck)
     95 			goto cant;
     96 		target = range(ms, closest);
     97 		if (target > rangeofshot[load] || !guns && target >= 3)
     98 			goto cant;
     99 		Signal("%s (%c%c) within range of %s broadside.",
    100 			closest, r ? "right" : "left");
    101 		if (load > L_CHAIN && target < 6) {
    102 			switch (sgetch("Aim for hull or rigging? ",
    103 				(struct ship *)0, 1)) {
    104 			case 'r':
    105 				shootat = RIGGING;
    106 				break;
    107 			case 'h':
    108 				shootat = HULL;
    109 				break;
    110 			default:
    111 				shootat = -1;
    112 				Signal("'Avast there! Hold your fire.'",
    113 					(struct ship *)0);
    114 			}
    115 		} else {
    116 			if (sgetch("Fire? ", (struct ship *)0, 1) == 'n') {
    117 				shootat = -1;
    118 				Signal("Belay that! Hold your fire.",
    119 					(struct ship *)0);
    120 			} else
    121 				shootat = RIGGING;
    122 		}
    123 		if (shootat == -1)
    124 			continue;
    125 		fired = 1;
    126 		rakehim = gunsbear(ms, closest) && !gunsbear(closest, ms);
    127 		temp = portside(closest, ms, 1) - closest->file->dir + 1;
    128 		if (temp < 1)
    129 			temp += 8;
    130 		else if (temp > 8)
    131 			temp -= 8;
    132 		sternrake = temp > 4 && temp < 6;
    133 		if (rakehim)
    134 			if (!sternrake)
    135 				Signal("Raking the %s!", closest);
    136 			else
    137 				Signal("Stern Rake! %s splintering!", closest);
    138 		index = guns;
    139 		if (target < 3)
    140 			index += car;
    141 		index = (index - 1)/3;
    142 		index = index > 8 ? 8 : index;
    143 		if (!rakehim)
    144 			hit = HDT[index][target-1];
    145 		else
    146 			hit = HDTrake[index][target-1];
    147 		if (rakehim && sternrake)
    148 			hit++;
    149 		hit += QUAL[index][mc->qual-1];
    150 		for (n = 0; n < 3 && mf->captured == 0; n++)
    151 			if (!crew[n])
    152 				if (index <= 5)
    153 					hit--;
    154 				else
    155 					hit -= 2;
    156 		if (ready & R_INITIAL)
    157 			if (index <= 3)
    158 				hit++;
    159 			else
    160 				hit += 2;
    161 		if (mf->captured != 0)
    162 			if (index <= 1)
    163 				hit--;
    164 			else
    165 				hit -= 2;
    166 		hit += AMMO[index][load - 1];
    167 		if (((temp = mc->class) >= 5 || temp == 1) && windspeed == 5)
    168 			hit--;
    169 		if (windspeed == 6 && temp == 4)
    170 			hit -= 2;
    171 		if (windspeed == 6 && temp <= 3)
    172 			hit--;
    173 		if (hit >= 0) {
    174 			roll = die();
    175 			if (load == L_GRAPE)
    176 				chits = hit;
    177 			else {
    178 				struct Tables *t;
    179 				if (hit > 10)
    180 					hit = 10;
    181 				t = &(shootat == RIGGING ? RigTable : HullTable)
    182 					[hit][roll-1];
    183 				chits = t->C;
    184 				rhits = t->R;
    185 				hhits = t->H;
    186 				ghits = t->G;
    187 				if (closest->file->FS)
    188 					rhits *= 2;
    189 				if (load == L_CHAIN) {
    190 					ghits = 0;
    191 					hhits = 0;
    192 				}
    193 			}
    194 			table(shootat, load, hit, closest, ms, roll);
    195 		}
    196 		Signal("Damage inflicted on the %s:",
    197 			(struct ship *)0, closest->shipname);
    198 		Signal("\t%d HULL, %d GUNS, %d CREW, %d RIGGING",
    199 			(struct ship *)0, hhits, ghits, chits, rhits);
    200 		if (!r) {
    201 			mf->loadL = L_EMPTY;
    202 			mf->readyL = R_EMPTY;
    203 		} else {
    204 			mf->loadR = L_EMPTY;
    205 			mf->readyR = R_EMPTY;
    206 		}
    207 		continue;
    208 	cant:
    209 		Signal("Unable to fire %s broadside",
    210 			(struct ship *)0, r ? "right" : "left");
    211 	}
    212 	blockalarm();
    213 	draw_stat();
    214 	unblockalarm();
    215 }
    216 
    217 grapungrap()
    218 {
    219 	register struct ship *sp;
    220 	register int i;
    221 
    222 	foreachship(sp) {
    223 		if (sp == ms || sp->file->dir == 0)
    224 			continue;
    225 		if (range(ms, sp) > 1 && !grappled2(ms, sp))
    226 			continue;
    227 		switch (sgetch("Attempt to grapple or ungrapple %s (%c%c): ",
    228 			sp, 1)) {
    229 		case 'g':
    230 			if (die() < 3
    231 			    || ms->nationality == capship(sp)->nationality) {
    232 				Write(W_GRAP, ms, 0, sp->file->index, 0, 0, 0);
    233 				Write(W_GRAP, sp, 0, player, 0, 0, 0);
    234 				Signal("Attempt succeeds!", (struct ship *)0);
    235 				makesignal(ms, "grappled with %s (%c%c)", sp);
    236 			} else
    237 				Signal("Attempt fails.", (struct ship *)0);
    238 			break;
    239 		case 'u':
    240 			for (i = grappled2(ms, sp); --i >= 0;) {
    241 				if (ms->nationality
    242 					== capship(sp)->nationality
    243 				    || die() < 3) {
    244 					cleangrapple(ms, sp, 0);
    245 					Signal("Attempt succeeds!",
    246 						(struct ship *)0);
    247 					makesignal(ms,
    248 						"ungrappling with %s (%c%c)",
    249 						sp);
    250 				} else
    251 					Signal("Attempt fails.",
    252 						(struct ship *)0);
    253 			}
    254 			break;
    255 		}
    256 	}
    257 }
    258 
    259 unfoulplayer()
    260 {
    261 	register struct ship *to;
    262 	register i;
    263 
    264 	foreachship(to) {
    265 		if (fouled2(ms, to) == 0)
    266 			continue;
    267 		if (sgetch("Attempt to unfoul with the %s (%c%c)? ", to, 1) != 'y')
    268 			continue;
    269 		for (i = fouled2(ms, to); --i >= 0;) {
    270 			if (die() <= 2) {
    271 				cleanfoul(ms, to, 0);
    272 				Signal("Attempt succeeds!", (struct ship *)0);
    273 				makesignal(ms, "Unfouling %s (%c%c)", to);
    274 			} else
    275 				Signal("Attempt fails.", (struct ship *)0);
    276 		}
    277 	}
    278 }
    279