pl_3.c 6.8 KB

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