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