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