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