1 /* $NetBSD: hack.u_init.c,v 1.6 2001/03/25 20:44:03 jsm Exp $ */ 2 3 /* 4 * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. 5 */ 6 7 #include <sys/cdefs.h> 8 #ifndef lint 9 __RCSID("$NetBSD: hack.u_init.c,v 1.6 2001/03/25 20:44:03 jsm Exp $"); 10 #endif /* not lint */ 11 12 #include <ctype.h> 13 #include <signal.h> 14 #include <stdlib.h> 15 #include "hack.h" 16 #include "extern.h" 17 18 #define Strcpy (void) strcpy 19 #define Strcat (void) strcat 20 #define UNDEF_TYP 0 21 #define UNDEF_SPE '\177' 22 23 struct you zerou; 24 char pl_character[PL_CSIZ]; 25 const char *(roles[]) = { /* must all have distinct first letter */ 26 /* roles[4] may be changed to -woman */ 27 "Tourist", "Speleologist", "Fighter", "Knight", 28 "Cave-man", "Wizard" 29 }; 30 #define NR_OF_ROLES SIZE(roles) 31 char rolesyms[NR_OF_ROLES + 1]; /* filled by u_init() */ 32 33 struct trobj { 34 uchar trotyp; 35 schar trspe; 36 char trolet; 37 Bitfield(trquan, 6); 38 Bitfield(trknown, 1); 39 }; 40 41 #ifdef WIZARD 42 struct trobj Extra_objs[] = { 43 {0, 0, 0, 0, 0}, 44 {0, 0, 0, 0, 0} 45 }; 46 #endif /* WIZARD */ 47 48 struct trobj Cave_man[] = { 49 {MACE, 1, WEAPON_SYM, 1, 1}, 50 {BOW, 1, WEAPON_SYM, 1, 1}, 51 {ARROW, 0, WEAPON_SYM, 25, 1}, /* quan is variable */ 52 {LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1}, 53 {0, 0, 0, 0, 0} 54 }; 55 56 struct trobj Fighter[] = { 57 {TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1}, 58 {RING_MAIL, 0, ARMOR_SYM, 1, 1}, 59 {0, 0, 0, 0, 0} 60 }; 61 62 struct trobj Knight[] = { 63 {LONG_SWORD, 0, WEAPON_SYM, 1, 1}, 64 {SPEAR, 2, WEAPON_SYM, 1, 1}, 65 {RING_MAIL, 1, ARMOR_SYM, 1, 1}, 66 {HELMET, 0, ARMOR_SYM, 1, 1}, 67 {SHIELD, 0, ARMOR_SYM, 1, 1}, 68 {PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1}, 69 {0, 0, 0, 0, 0} 70 }; 71 72 struct trobj Speleologist[] = { 73 {STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1}, 74 {UNDEF_TYP, 0, POTION_SYM, 2, 0}, 75 {FOOD_RATION, 0, FOOD_SYM, 3, 1}, 76 {PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0}, 77 {ICE_BOX, 0, TOOL_SYM, 1, 0}, 78 {0, 0, 0, 0, 0} 79 }; 80 81 struct trobj Tinopener[] = { 82 {CAN_OPENER, 0, TOOL_SYM, 1, 1}, 83 {0, 0, 0, 0, 0} 84 }; 85 86 struct trobj Tourist[] = { 87 {UNDEF_TYP, 0, FOOD_SYM, 10, 1}, 88 {POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0}, 89 {EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1}, 90 {DART, 2, WEAPON_SYM, 25, 1}, /* quan is variable */ 91 {0, 0, 0, 0, 0} 92 }; 93 94 struct trobj Wizard[] = { 95 {ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1}, 96 {UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0}, 97 {UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0}, 98 {UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0}, 99 {UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0}, 100 {0, 0, 0, 0, 0} 101 }; 102 103 void 104 u_init() 105 { 106 int i; 107 char exper = 'y', pc; 108 if (flags.female) /* should have been set in HACKOPTIONS */ 109 roles[4] = "Cave-woman"; 110 for (i = 0; i < NR_OF_ROLES; i++) 111 rolesyms[i] = roles[i][0]; 112 rolesyms[i] = 0; 113 114 if ((pc = pl_character[0]) != '\0') { 115 if (islower(pc)) 116 pc = toupper(pc); 117 if ((i = role_index(pc)) >= 0) 118 goto got_suffix; /* implies experienced */ 119 printf("\nUnknown role: %c\n", pc); 120 pl_character[0] = pc = 0; 121 } 122 printf("\nAre you an experienced player? [ny] "); 123 124 while (!strchr("ynYN \n\004", (exper = readchar()))) 125 bell(); 126 if (exper == '\004') /* Give him an opportunity to get out */ 127 end_of_input(); 128 printf("%c\n", exper); /* echo */ 129 if (strchr("Nn \n", exper)) { 130 exper = 0; 131 goto beginner; 132 } 133 printf("\nTell me what kind of character you are:\n"); 134 printf("Are you"); 135 for (i = 0; i < NR_OF_ROLES; i++) { 136 printf(" a %s", roles[i]); 137 if (i == 2) /* %% */ 138 printf(",\n\t"); 139 else if (i < NR_OF_ROLES - 2) 140 printf(","); 141 else if (i == NR_OF_ROLES - 2) 142 printf(" or"); 143 } 144 printf("? [%s] ", rolesyms); 145 146 while ((pc = readchar()) != '\0') { 147 if (islower(pc)) 148 pc = toupper(pc); 149 if ((i = role_index(pc)) >= 0) { 150 printf("%c\n", pc); /* echo */ 151 (void) fflush(stdout); /* should be seen */ 152 break; 153 } 154 if (pc == '\n') 155 break; 156 if (pc == '\004') /* Give him the opportunity to get 157 * out */ 158 end_of_input(); 159 bell(); 160 } 161 if (pc == '\n') 162 pc = 0; 163 164 beginner: 165 if (!pc) { 166 printf("\nI'll choose a character for you.\n"); 167 i = rn2(NR_OF_ROLES); 168 pc = rolesyms[i]; 169 printf("This game you will be a%s %s.\n", 170 exper ? "n experienced" : "", 171 roles[i]); 172 getret(); 173 /* give him some feedback in case mklev takes much time */ 174 (void) putchar('\n'); 175 (void) fflush(stdout); 176 } 177 #if 0 178 /* 179 * Given the above code, I can't see why this would ever change 180 * anything; it does core pretty well, though. - cmh 4/20/93 181 */ 182 if (exper) { 183 roles[i][0] = pc; 184 } 185 #endif 186 187 got_suffix: 188 189 (void) strncpy(pl_character, roles[i], PL_CSIZ - 1); 190 pl_character[PL_CSIZ - 1] = 0; 191 flags.beginner = 1; 192 u = zerou; 193 u.usym = '@'; 194 u.ulevel = 1; 195 init_uhunger(); 196 #ifdef QUEST 197 u.uhorizon = 6; 198 #endif /* QUEST */ 199 uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain = 200 uleft = uright = 0; 201 202 switch (pc) { 203 case 'c': 204 case 'C': 205 Cave_man[2].trquan = 12 + rnd(9) * rnd(9); 206 u.uhp = u.uhpmax = 16; 207 u.ustr = u.ustrmax = 18; 208 ini_inv(Cave_man); 209 break; 210 case 't': 211 case 'T': 212 Tourist[3].trquan = 20 + rnd(20); 213 u.ugold = u.ugold0 = rnd(1000); 214 u.uhp = u.uhpmax = 10; 215 u.ustr = u.ustrmax = 8; 216 ini_inv(Tourist); 217 if (!rn2(25)) 218 ini_inv(Tinopener); 219 break; 220 case 'w': 221 case 'W': 222 for (i = 1; i <= 4; i++) 223 if (!rn2(5)) 224 Wizard[i].trquan += rn2(3) - 1; 225 u.uhp = u.uhpmax = 15; 226 u.ustr = u.ustrmax = 16; 227 ini_inv(Wizard); 228 break; 229 case 's': 230 case 'S': 231 Fast = INTRINSIC; 232 Stealth = INTRINSIC; 233 u.uhp = u.uhpmax = 12; 234 u.ustr = u.ustrmax = 10; 235 ini_inv(Speleologist); 236 if (!rn2(10)) 237 ini_inv(Tinopener); 238 break; 239 case 'k': 240 case 'K': 241 u.uhp = u.uhpmax = 12; 242 u.ustr = u.ustrmax = 10; 243 ini_inv(Knight); 244 break; 245 case 'f': 246 case 'F': 247 u.uhp = u.uhpmax = 14; 248 u.ustr = u.ustrmax = 17; 249 ini_inv(Fighter); 250 break; 251 default: /* impossible */ 252 u.uhp = u.uhpmax = 12; 253 u.ustr = u.ustrmax = 16; 254 } 255 find_ac(); 256 if (!rn2(20)) { 257 int d = rn2(7) - 2; /* biased variation */ 258 u.ustr += d; 259 u.ustrmax += d; 260 } 261 #ifdef WIZARD 262 if (wizard) 263 wiz_inv(); 264 #endif /* WIZARD */ 265 266 /* make sure he can carry all he has - especially for T's */ 267 while (inv_weight() > 0 && u.ustr < 118) 268 u.ustr++, u.ustrmax++; 269 } 270 271 void 272 ini_inv(trop) 273 struct trobj *trop; 274 { 275 struct obj *obj; 276 while (trop->trolet) { 277 obj = mkobj(trop->trolet); 278 obj->known = trop->trknown; 279 /* not obj->dknown = 1; - let him look at it at least once */ 280 obj->cursed = 0; 281 if (obj->olet == WEAPON_SYM) { 282 obj->quan = trop->trquan; 283 trop->trquan = 1; 284 } 285 if (trop->trspe != UNDEF_SPE) 286 obj->spe = trop->trspe; 287 if (trop->trotyp != UNDEF_TYP) 288 obj->otyp = trop->trotyp; 289 else if (obj->otyp == WAN_WISHING) /* gitpyr!robert */ 290 obj->otyp = WAN_DEATH; 291 obj->owt = weight(obj); /* defined after setting otyp+quan */ 292 obj = addinv(obj); 293 if (obj->olet == ARMOR_SYM) { 294 switch (obj->otyp) { 295 case SHIELD: 296 if (!uarms) 297 setworn(obj, W_ARMS); 298 break; 299 case HELMET: 300 if (!uarmh) 301 setworn(obj, W_ARMH); 302 break; 303 case PAIR_OF_GLOVES: 304 if (!uarmg) 305 setworn(obj, W_ARMG); 306 break; 307 case ELVEN_CLOAK: 308 if (!uarm2) 309 setworn(obj, W_ARM); 310 break; 311 default: 312 if (!uarm) 313 setworn(obj, W_ARM); 314 } 315 } 316 if (obj->olet == WEAPON_SYM) 317 if (!uwep) 318 setuwep(obj); 319 #ifndef PYRAMID_BUG 320 if (--trop->trquan) 321 continue; /* make a similar object */ 322 #else 323 if (trop->trquan) { /* check if zero first */ 324 --trop->trquan; 325 if (trop->trquan) 326 continue; /* make a similar object */ 327 } 328 #endif /* PYRAMID_BUG */ 329 trop++; 330 } 331 } 332 333 #ifdef WIZARD 334 void 335 wiz_inv() 336 { 337 struct trobj *trop = &Extra_objs[0]; 338 char *ep = getenv("INVENT"); 339 int type; 340 while (ep && *ep) { 341 type = atoi(ep); 342 ep = strchr(ep, ','); 343 if (ep) 344 while (*ep == ',' || *ep == ' ') 345 ep++; 346 if (type <= 0 || type > NROFOBJECTS) 347 continue; 348 trop->trotyp = type; 349 trop->trolet = objects[type].oc_olet; 350 trop->trspe = 4; 351 trop->trknown = 1; 352 trop->trquan = 1; 353 ini_inv(trop); 354 } 355 /* give him a wand of wishing by default */ 356 trop->trotyp = WAN_WISHING; 357 trop->trolet = WAND_SYM; 358 trop->trspe = 20; 359 trop->trknown = 1; 360 trop->trquan = 1; 361 ini_inv(trop); 362 } 363 #endif /* WIZARD */ 364 365 void 366 plnamesuffix() 367 { 368 char *p; 369 if ((p = strrchr(plname, '-')) != NULL) { 370 *p = 0; 371 pl_character[0] = p[1]; 372 pl_character[1] = 0; 373 if (!plname[0]) { 374 askname(); 375 plnamesuffix(); 376 } 377 } 378 } 379 380 int 381 role_index(pc) 382 char pc; 383 { /* must be called only from u_init() */ 384 /* so that rolesyms[] is defined */ 385 char *cp; 386 387 if ((cp = strchr(rolesyms, pc)) != NULL) 388 return (cp - rolesyms); 389 return (-1); 390 } 391