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