assorted.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /* $NetBSD: assorted.c,v 1.15 2003/08/07 09:37:41 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[] = "@(#)assorted.c 8.2 (Berkeley) 4/28/95";
  34. #else
  35. __RCSID("$NetBSD: assorted.c,v 1.15 2003/08/07 09:37:41 agc Exp $");
  36. #endif
  37. #endif /* not lint */
  38. #include <stdlib.h>
  39. #include <err.h>
  40. #include "extern.h"
  41. static void strike (struct ship *, struct ship *);
  42. void
  43. table(struct ship *from, struct ship *on, int rig, int shot, int hittable, int roll)
  44. {
  45. int hhits = 0, chits = 0, ghits = 0, rhits = 0;
  46. int Ghit = 0, Hhit = 0, Rhit = 0, Chit = 0;
  47. int guns, car, pc, hull;
  48. int crew[3];
  49. int n;
  50. int rigg[4];
  51. const char *message;
  52. const struct Tables *tp;
  53. pc = on->file->pcrew;
  54. hull = on->specs->hull;
  55. crew[0] = on->specs->crew1;
  56. crew[1] = on->specs->crew2;
  57. crew[2] = on->specs->crew3;
  58. rigg[0] = on->specs->rig1;
  59. rigg[1] = on->specs->rig2;
  60. rigg[2] = on->specs->rig3;
  61. rigg[3] = on->specs->rig4;
  62. if (shot == L_GRAPE)
  63. Chit = chits = hittable;
  64. else {
  65. tp = &(rig ? RigTable : HullTable)[hittable][roll-1];
  66. Chit = chits = tp->C;
  67. Rhit = rhits = tp->R;
  68. Hhit = hhits = tp->H;
  69. Ghit = ghits = tp->G;
  70. if (on->file->FS)
  71. rhits *= 2;
  72. if (shot == L_CHAIN) {
  73. Ghit = ghits = 0;
  74. Hhit = hhits = 0;
  75. }
  76. }
  77. if (on->file->captured != 0) {
  78. pc -= (chits + 1) / 2;
  79. chits /= 2;
  80. }
  81. for (n = 0; n < 3; n++)
  82. if (chits > crew[n]) {
  83. chits -= crew[n];
  84. crew[n] = 0;
  85. } else {
  86. crew[n] -= chits;
  87. chits = 0;
  88. }
  89. for (n = 0; n < 3; n++)
  90. if (rhits > rigg[n]){
  91. rhits -= rigg[n];
  92. rigg[n] = 0;
  93. } else {
  94. rigg[n] -= rhits;
  95. rhits = 0;
  96. }
  97. if (rigg[3] != -1 && rhits > rigg[3]) {
  98. rhits -= rigg[3];
  99. rigg[3] = 0;
  100. } else if (rigg[3] != -1) {
  101. rigg[3] -= rhits;
  102. }
  103. if (rig && !rigg[2] && (!rigg[3] || rigg[3] == -1))
  104. makemsg(on, "dismasted!");
  105. if (portside(from, on, 0)) {
  106. guns = on->specs->gunR;
  107. car = on->specs->carR;
  108. } else {
  109. guns = on->specs->gunL;
  110. car = on->specs->carL;
  111. }
  112. if (ghits > car) {
  113. ghits -= car;
  114. car = 0;
  115. } else {
  116. car -= ghits;
  117. ghits = 0;
  118. }
  119. if (ghits > guns){
  120. ghits -= guns;
  121. guns = 0;
  122. } else {
  123. guns -= ghits;
  124. ghits = 0;
  125. }
  126. hull -= ghits;
  127. if (Ghit)
  128. Write(portside(from, on, 0) ? W_GUNR : W_GUNL,
  129. on, guns, car, 0, 0);
  130. hull -= hhits;
  131. hull = hull < 0 ? 0 : hull;
  132. if (on->file->captured != 0 && Chit)
  133. Write(W_PCREW, on, pc, 0, 0, 0);
  134. if (Hhit)
  135. Write(W_HULL, on, hull, 0, 0, 0);
  136. if (Chit)
  137. Write(W_CREW, on, crew[0], crew[1], crew[2], 0);
  138. if (Rhit)
  139. Write(W_RIGG, on, rigg[0], rigg[1], rigg[2], rigg[3]);
  140. switch (shot) {
  141. case L_ROUND:
  142. message = "firing round shot on $$";
  143. break;
  144. case L_GRAPE:
  145. message = "firing grape shot on $$";
  146. break;
  147. case L_CHAIN:
  148. message = "firing chain shot on $$";
  149. break;
  150. case L_DOUBLE:
  151. message = "firing double shot on $$";
  152. break;
  153. case L_EXPLODE:
  154. message = "exploding shot on $$";
  155. break;
  156. default:
  157. errx(1, "Unknown shot type %d", shot);
  158. }
  159. makesignal(from, message, on);
  160. if (roll == 6 && rig) {
  161. switch(Rhit) {
  162. case 0:
  163. message = "fore topsail sheets parted";
  164. break;
  165. case 1:
  166. message = "mizzen shrouds parted";
  167. break;
  168. case 2:
  169. message = "main topsail yard shot away";
  170. break;
  171. case 4:
  172. message = "fore topmast and foremast shrouds shot away";
  173. break;
  174. case 5:
  175. message = "mizzen mast and yard shot through";
  176. break;
  177. case 6:
  178. message = "foremast and spritsail yard shattered";
  179. break;
  180. case 7:
  181. message = "main topmast and mizzen mast shattered";
  182. break;
  183. default:
  184. errx(1, "Bad Rhit = %d", Rhit);
  185. }
  186. makemsg(on, message);
  187. } else if (roll == 6) {
  188. switch (Hhit) {
  189. case 0:
  190. message = "anchor cables severed";
  191. break;
  192. case 1:
  193. message = "two anchor stocks shot away";
  194. break;
  195. case 2:
  196. message = "quarterdeck bulwarks damaged";
  197. break;
  198. case 3:
  199. message = "three gun ports shot away";
  200. break;
  201. case 4:
  202. message = "four guns dismounted";
  203. break;
  204. case 5:
  205. message = "rudder cables shot through";
  206. Write(W_TA, on, 0, 0, 0, 0);
  207. break;
  208. case 6:
  209. message = "shot holes below the water line";
  210. break;
  211. default:
  212. errx(1, "Bad Hhit = %d", Hhit);
  213. }
  214. makemsg(on, message);
  215. }
  216. /*
  217. if (Chit > 1 && on->file->readyL&R_INITIAL && on->file->readyR&R_INITIAL) {
  218. on->specs->qual--;
  219. if (on->specs->qual <= 0) {
  220. makemsg(on, "crew mutinying!");
  221. on->specs->qual = 5;
  222. Write(W_CAPTURED, on, on->file->index, 0, 0, 0);
  223. } else
  224. makemsg(on, "crew demoralized");
  225. Write(W_QUAL, on, on->specs->qual, 0, 0, 0);
  226. }
  227. */
  228. if (!hull)
  229. strike(on, from);
  230. }
  231. void
  232. Cleansnag(struct ship *from, struct ship *to, int all, int flag)
  233. {
  234. if (flag & 1) {
  235. Write(W_UNGRAP, from, to->file->index, all, 0, 0);
  236. Write(W_UNGRAP, to, from->file->index, all, 0, 0);
  237. }
  238. if (flag & 2) {
  239. Write(W_UNFOUL, from, to->file->index, all, 0, 0);
  240. Write(W_UNFOUL, to, from->file->index, all, 0, 0);
  241. }
  242. if (!snagged2(from, to)) {
  243. if (!snagged(from)) {
  244. unboard(from, from, 1); /* defense */
  245. unboard(from, from, 0); /* defense */
  246. } else
  247. unboard(from, to, 0); /* offense */
  248. if (!snagged(to)) {
  249. unboard(to, to, 1); /* defense */
  250. unboard(to, to, 0); /* defense */
  251. } else
  252. unboard(to, from, 0); /* offense */
  253. }
  254. }
  255. static void
  256. strike(struct ship *ship, struct ship *from)
  257. {
  258. int points;
  259. if (ship->file->struck)
  260. return;
  261. Write(W_STRUCK, ship, 1, 0, 0, 0);
  262. points = ship->specs->pts + from->file->points;
  263. Write(W_POINTS, from, points, 0, 0, 0);
  264. unboard(ship, ship, 0); /* all offense */
  265. unboard(ship, ship, 1); /* all defense */
  266. switch (dieroll()) {
  267. case 3:
  268. case 4: /* ship may sink */
  269. Write(W_SINK, ship, 1, 0, 0, 0);
  270. break;
  271. case 5:
  272. case 6: /* ship may explode */
  273. Write(W_EXPLODE, ship, 1, 0, 0, 0);
  274. break;
  275. }
  276. Writestr(W_SIGNAL, ship, "striking her colours!");
  277. }