1/* $OpenBSD: command7.c,v 1.1 2020/12/15 00:38:18 daniel Exp $ */ 2/* $NetBSD: com7.c,v 1.3 1995/03/21 15:07:12 cgd Exp $ */ 3 4/* 5 * Copyright (c) 1983, 1993 6 * The Regents of the University of California. All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the University nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33#include <stdio.h> 34#include <stdlib.h> 35 36#include "extern.h" 37 38int 39fight(int enemy, int strength) 40{ 41 int lifeline = 0; 42 int hurt; 43 char auxbuf[LINELENGTH]; 44 char *next; 45 int i; 46 int exhaustion; 47 48 stop_cypher = 1; /* Don't parse the existing input line further */ 49fighton: 50 ourtime++; 51 snooze -= 5; 52 if (snooze > ourtime) 53 exhaustion = CYCLE / (snooze - ourtime); 54 else { 55 puts("You collapse exhausted and he pulverizes your skull."); 56 die(0); 57 } 58 if (snooze - ourtime < 20) 59 puts("You look tired! I hope you're able to fight."); 60 next = getcom(auxbuf, LINELENGTH, "<fight!>-: ", NULL); 61 for (i = 0; next && i < NWORD - 1; i++) 62 next = getword(next, words[i], -1); 63 parse(); 64 switch (wordvalue[wordnumber]) { 65 66 case KILL: 67 case SMITE: 68 if (TestBit(inven, TWO_HANDED)) 69 hurt = rnd(70) - 2 * card(injuries, NUMOFINJURIES) - ucard(wear) - exhaustion; 70 else if (TestBit(inven, SWORD) || TestBit(inven, BROAD)) 71 hurt = rnd(50) % (WEIGHT - carrying) - card(injuries, NUMOFINJURIES) - encumber - exhaustion; 72 else if (TestBit(inven, KNIFE) || TestBit(inven, MALLET) || TestBit(inven, CHAIN) || TestBit(inven, MACE) || TestBit(inven, HALBERD)) 73 hurt = rnd(15) - card(injuries, NUMOFINJURIES) - exhaustion; 74 else 75 hurt = rnd(7) - encumber; 76 if (hurt < 5) 77 switch (rnd(3)) { 78 79 case 0: 80 puts("You swung wide and missed."); 81 break; 82 case 1: 83 puts("He checked your blow. CLASH! CLANG!"); 84 break; 85 case 2: 86 puts("His filthy tunic hangs by one less thread."); 87 break; 88 } 89 else if (hurt < 10) { 90 switch (rnd(3)) { 91 case 0: 92 puts("He's bleeding."); 93 break; 94 case 1: 95 puts("A trickle of blood runs down his face."); 96 break; 97 case 2: 98 puts("A huge purple bruise is forming on the side of his face."); 99 break; 100 } 101 lifeline++; 102 } 103 else if (hurt < 20) { 104 switch (rnd(3)) { 105 case 0: 106 puts("He staggers back quavering."); 107 break; 108 case 1: 109 puts("He jumps back with his hand over the wound."); 110 break; 111 case 2: 112 puts("His shirt falls open with a swath across the chest."); 113 break; 114 } 115 lifeline += 5; 116 } 117 else if (hurt < 30) { 118 switch (rnd(3)) { 119 case 0: 120 printf("A bloody gash opens up on his %s side.\n",(rnd(2) ? "left" : "right")); 121 break; 122 case 1: 123 puts("The steel bites home and scrapes along his ribs."); 124 break; 125 case 2: 126 puts("You pierce him, and his breath hisses through clenched teeth."); 127 break; 128 } 129 lifeline += 10; 130 } 131 else if (hurt < 40) { 132 switch (rnd(3)) { 133 case 0: 134 puts("You smite him to the ground."); 135 if (strength - lifeline > 20) 136 puts("But in a flurry of steel he regains his feet!"); 137 break; 138 case 1: 139 puts("The force of your blow sends him to his knees."); 140 puts("His arm swings lifeless at his side."); 141 break; 142 case 2: 143 puts("Clutching his blood-drenched shirt, he collapses, stunned."); 144 break; 145 } 146 lifeline += 20; 147 } 148 else { 149 switch (rnd(3)) { 150 case 0: 151 puts("His ribs crack under your powerful swing, flooding his lungs with blood."); 152 break; 153 case 1: 154 puts("You shatter his upheld arm in a spray of blood. The blade continues deep"); 155 puts("into his back, severing the spinal cord."); 156 lifeline += 25; 157 break; 158 case 2: 159 puts("With a mighty lunge the steel slides in, and gasping, he falls to the ground."); 160 lifeline += 25; 161 break; 162 } 163 lifeline += 30; 164 } 165 break; 166 167 case BACK: 168 if (enemy == DARK && lifeline > strength * 0.33) { 169 puts("He throws you back against the rock and pummels your face."); 170 if (TestBit(inven, AMULET) || TestBit(wear, AMULET)) { 171 printf("Lifting the amulet from you, "); 172 if (TestBit(inven, MEDALION) || TestBit(wear, MEDALION)) { 173 puts("his power grows and the walls of\nthe earth tremble."); 174 puts("When he touches the medallion, your chest explodes and the foundations of the\nearth collapse."); 175 puts("The planet is consumed by darkness."); 176 die(0); 177 } 178 if (TestBit(inven, AMULET)) { 179 ClearBit(inven, AMULET); 180 carrying -= objwt[AMULET]; 181 encumber -= objcumber[AMULET]; 182 } else 183 ClearBit(wear, AMULET); 184 puts("he flees down the dark caverns."); 185 ClearBit(location[position].objects, DARK); 186 injuries[SKULL] = 1; 187 followfight = ourtime; 188 return (0); 189 } else { 190 puts("I'm afraid you have been killed."); 191 die(0); 192 } 193 } else { 194 puts("You escape stunned and disoriented from the fight."); 195 puts("A victorious bellow echoes from the battlescene."); 196 if (back && position != back) 197 moveplayer(back, BACK); 198 else if (ahead &&position != ahead) 199 moveplayer(ahead, AHEAD); 200 else if (left && position != left) 201 moveplayer(left, LEFT); 202 else if (right && position != right) 203 moveplayer(right, RIGHT); 204 else 205 moveplayer(location[position].down, AHEAD); 206 return (0); 207 } 208 209 case SHOOT: 210 if (TestBit(inven, LASER)) { 211 if (strength - lifeline <= 50) { 212 printf("The %s took a direct hit!\n", objsht[enemy]); 213 lifeline += 50; 214 } else { 215 puts("With his bare hand he deflects the laser blast and whips the pistol from you!"); 216 ClearBit(inven, LASER); 217 SetBit(location[position].objects, LASER); 218 carrying -= objwt[LASER]; 219 encumber -= objcumber[LASER]; 220 } 221 } else 222 puts("Unfortunately, you don't have a blaster handy."); 223 break; 224 225 case DROP: 226 case DRAW: 227 /* One call to cypher() does only the first command on the line */ 228 cypher(); 229 ourtime--; 230 break; 231 232 default: 233 puts("You don't have a chance; he is too quick."); 234 break; 235 236 } 237 if (lifeline >= strength) { 238 printf("You have killed the %s.\n", objsht[enemy]); 239 if (enemy == ELF || enemy == DARK) 240 puts("A watery black smoke consumes his body and then vanishes with a peal of thunder!"); 241 ClearBit(location[position].objects, enemy); 242 power += 2; 243 notes[JINXED]++; 244 return (0); 245 } 246 puts("He attacks..."); 247 /* some embellishments */ 248 hurt = rnd(NUMOFINJURIES) - (TestBit(inven, SHIELD) != 0) - (TestBit(wear, MAIL) != 0) - (TestBit(wear, HELM) != 0); 249 hurt += (TestBit(wear, AMULET) != 0) + (TestBit(wear, MEDALION) != 0) + (TestBit(wear, TALISMAN) != 0); 250 hurt = hurt < 0 ? 0 : hurt; 251 hurt = hurt >= NUMOFINJURIES ? NUMOFINJURIES - 1 : hurt; 252 if (!injuries[hurt]) { 253 injuries[hurt] = 1; 254 printf("I'm afraid you have suffered %s.\n", ouch[hurt]); 255 } else 256 puts("You emerge unscathed."); 257 if (injuries[SKULL] && injuries[INCISE] && injuries[NECK]) { 258 puts("I'm afraid you have suffered fatal injuries."); 259 die(0); 260 } 261 goto fighton; 262} 263