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