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