1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2 /* hack.u_init.c - version 1.0.3 */ 3 4 #include "hack.h" 5 #include <stdio.h> 6 #include <signal.h> 7 #define Strcpy (void) strcpy 8 #define Strcat (void) strcat 9 #define UNDEF_TYP 0 10 #define UNDEF_SPE '\177' 11 extern struct obj *addinv(); 12 extern char *eos(); 13 extern char plname[]; 14 15 struct you zerou; 16 char pl_character[PL_CSIZ]; 17 char *(roles[]) = { /* must all have distinct first letter */ 18 /* roles[4] may be changed to -woman */ 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 u_init(){ 96 register int i; 97 char exper = 'y', pc; 98 extern char readchar(); 99 if(flags.female) /* should have been set in HACKOPTIONS */ 100 roles[4] = "Cave-woman"; 101 for(i = 0; i < NR_OF_ROLES; i++) 102 rolesyms[i] = roles[i][0]; 103 rolesyms[i] = 0; 104 105 if(pc = pl_character[0]) { 106 if(islower(pc)) pc = toupper(pc); 107 if((i = role_index(pc)) >= 0) 108 goto got_suffix; /* implies experienced */ 109 printf("\nUnknown role: %c\n", pc); 110 pl_character[0] = pc = 0; 111 } 112 113 printf("\nAre you an experienced player? [ny] "); 114 115 while(!index("ynYN \n\004", (exper = readchar()))) 116 bell(); 117 if(exper == '\004') /* Give him an opportunity to get out */ 118 end_of_input(); 119 printf("%c\n", exper); /* echo */ 120 if(index("Nn \n", exper)) { 121 exper = 0; 122 goto beginner; 123 } 124 125 printf("\nTell me what kind of character you are:\n"); 126 printf("Are you"); 127 for(i = 0; i < NR_OF_ROLES; i++) { 128 printf(" a %s", roles[i]); 129 if(i == 2) /* %% */ 130 printf(",\n\t"); 131 else if(i < NR_OF_ROLES - 2) 132 printf(","); 133 else if(i == NR_OF_ROLES - 2) 134 printf(" or"); 135 } 136 printf("? [%s] ", rolesyms); 137 138 while(pc = readchar()) { 139 if(islower(pc)) pc = toupper(pc); 140 if((i = role_index(pc)) >= 0) { 141 printf("%c\n", pc); /* echo */ 142 (void) fflush(stdout); /* should be seen */ 143 break; 144 } 145 if(pc == '\n') 146 break; 147 if(pc == '\004') /* Give him the opportunity to get out */ 148 end_of_input(); 149 bell(); 150 } 151 if(pc == '\n') 152 pc = 0; 153 154 beginner: 155 if(!pc) { 156 printf("\nI'll choose a character for you.\n"); 157 i = rn2(NR_OF_ROLES); 158 pc = rolesyms[i]; 159 printf("This game you will be a%s %s.\n", 160 exper ? "n experienced" : "", 161 roles[i]); 162 getret(); 163 /* give him some feedback in case mklev takes much time */ 164 (void) putchar('\n'); 165 (void) fflush(stdout); 166 } 167 #if 0 168 /* Given the above code, I can't see why this would ever change 169 anything; it does core pretty well, though. - cmh 4/20/93 */ 170 if(exper) { 171 roles[i][0] = pc; 172 } 173 #endif 174 175 got_suffix: 176 177 (void) strncpy(pl_character, roles[i], PL_CSIZ-1); 178 pl_character[PL_CSIZ-1] = 0; 179 flags.beginner = 1; 180 u = zerou; 181 u.usym = '@'; 182 u.ulevel = 1; 183 init_uhunger(); 184 #ifdef QUEST 185 u.uhorizon = 6; 186 #endif QUEST 187 uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain = 188 uleft = uright = 0; 189 190 switch(pc) { 191 case 'c': 192 case 'C': 193 Cave_man[2].trquan = 12 + rnd(9)*rnd(9); 194 u.uhp = u.uhpmax = 16; 195 u.ustr = u.ustrmax = 18; 196 ini_inv(Cave_man); 197 break; 198 case 't': 199 case 'T': 200 Tourist[3].trquan = 20 + rnd(20); 201 u.ugold = u.ugold0 = rnd(1000); 202 u.uhp = u.uhpmax = 10; 203 u.ustr = u.ustrmax = 8; 204 ini_inv(Tourist); 205 if(!rn2(25)) ini_inv(Tinopener); 206 break; 207 case 'w': 208 case 'W': 209 for(i=1; i<=4; i++) if(!rn2(5)) 210 Wizard[i].trquan += rn2(3) - 1; 211 u.uhp = u.uhpmax = 15; 212 u.ustr = u.ustrmax = 16; 213 ini_inv(Wizard); 214 break; 215 case 's': 216 case 'S': 217 Fast = INTRINSIC; 218 Stealth = INTRINSIC; 219 u.uhp = u.uhpmax = 12; 220 u.ustr = u.ustrmax = 10; 221 ini_inv(Speleologist); 222 if(!rn2(10)) ini_inv(Tinopener); 223 break; 224 case 'k': 225 case 'K': 226 u.uhp = u.uhpmax = 12; 227 u.ustr = u.ustrmax = 10; 228 ini_inv(Knight); 229 break; 230 case 'f': 231 case 'F': 232 u.uhp = u.uhpmax = 14; 233 u.ustr = u.ustrmax = 17; 234 ini_inv(Fighter); 235 break; 236 default: /* impossible */ 237 u.uhp = u.uhpmax = 12; 238 u.ustr = u.ustrmax = 16; 239 } 240 find_ac(); 241 if(!rn2(20)) { 242 register int d = rn2(7) - 2; /* biased variation */ 243 u.ustr += d; 244 u.ustrmax += d; 245 } 246 247 #ifdef WIZARD 248 if(wizard) wiz_inv(); 249 #endif WIZARD 250 251 /* make sure he can carry all he has - especially for T's */ 252 while(inv_weight() > 0 && u.ustr < 118) 253 u.ustr++, u.ustrmax++; 254 } 255 256 ini_inv(trop) register struct trobj *trop; { 257 register struct obj *obj; 258 extern struct obj *mkobj(); 259 while(trop->trolet) { 260 obj = mkobj(trop->trolet); 261 obj->known = trop->trknown; 262 /* not obj->dknown = 1; - let him look at it at least once */ 263 obj->cursed = 0; 264 if(obj->olet == WEAPON_SYM){ 265 obj->quan = trop->trquan; 266 trop->trquan = 1; 267 } 268 if(trop->trspe != UNDEF_SPE) 269 obj->spe = trop->trspe; 270 if(trop->trotyp != UNDEF_TYP) 271 obj->otyp = trop->trotyp; 272 else 273 if(obj->otyp == WAN_WISHING) /* gitpyr!robert */ 274 obj->otyp = WAN_DEATH; 275 obj->owt = weight(obj); /* defined after setting otyp+quan */ 276 obj = addinv(obj); 277 if(obj->olet == ARMOR_SYM){ 278 switch(obj->otyp){ 279 case SHIELD: 280 if(!uarms) setworn(obj, W_ARMS); 281 break; 282 case HELMET: 283 if(!uarmh) setworn(obj, W_ARMH); 284 break; 285 case PAIR_OF_GLOVES: 286 if(!uarmg) setworn(obj, W_ARMG); 287 break; 288 case ELVEN_CLOAK: 289 if(!uarm2) 290 setworn(obj, W_ARM); 291 break; 292 default: 293 if(!uarm) setworn(obj, W_ARM); 294 } 295 } 296 if(obj->olet == WEAPON_SYM) 297 if(!uwep) setuwep(obj); 298 #ifndef PYRAMID_BUG 299 if(--trop->trquan) continue; /* make a similar object */ 300 #else 301 if(trop->trquan) { /* check if zero first */ 302 --trop->trquan; 303 if(trop->trquan) 304 continue; /* make a similar object */ 305 } 306 #endif PYRAMID_BUG 307 trop++; 308 } 309 } 310 311 #ifdef WIZARD 312 wiz_inv(){ 313 register struct trobj *trop = &Extra_objs[0]; 314 extern char *getenv(); 315 register char *ep = getenv("INVENT"); 316 register int type; 317 while(ep && *ep) { 318 type = atoi(ep); 319 ep = index(ep, ','); 320 if(ep) while(*ep == ',' || *ep == ' ') ep++; 321 if(type <= 0 || type > NROFOBJECTS) continue; 322 trop->trotyp = type; 323 trop->trolet = objects[type].oc_olet; 324 trop->trspe = 4; 325 trop->trknown = 1; 326 trop->trquan = 1; 327 ini_inv(trop); 328 } 329 /* give him a wand of wishing by default */ 330 trop->trotyp = WAN_WISHING; 331 trop->trolet = WAND_SYM; 332 trop->trspe = 20; 333 trop->trknown = 1; 334 trop->trquan = 1; 335 ini_inv(trop); 336 } 337 #endif WIZARD 338 339 plnamesuffix() { 340 register char *p; 341 if(p = rindex(plname, '-')) { 342 *p = 0; 343 pl_character[0] = p[1]; 344 pl_character[1] = 0; 345 if(!plname[0]) { 346 askname(); 347 plnamesuffix(); 348 } 349 } 350 } 351 352 role_index(pc) 353 char pc; 354 { /* must be called only from u_init() */ 355 /* so that rolesyms[] is defined */ 356 register char *cp; 357 358 if(cp = index(rolesyms, pc)) 359 return(cp - rolesyms); 360 return(-1); 361 } 362