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