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