Commit | Line | Data |
---|---|---|
53c1ce0d KB |
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 -man */ | |
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('a' <= pc && pc <= 'z') pc += 'A'-'a'; | |
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('a' <= pc && pc <= 'z') pc += 'A'-'a'; | |
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(exper) { | |
168 | roles[i][0] = pc; | |
169 | } | |
170 | ||
171 | got_suffix: | |
172 | ||
173 | (void) strncpy(pl_character, roles[i], PL_CSIZ-1); | |
174 | pl_character[PL_CSIZ-1] = 0; | |
175 | flags.beginner = 1; | |
176 | u = zerou; | |
177 | u.usym = '@'; | |
178 | u.ulevel = 1; | |
179 | init_uhunger(); | |
180 | #ifdef QUEST | |
181 | u.uhorizon = 6; | |
182 | #endif QUEST | |
183 | uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain = | |
184 | uleft = uright = 0; | |
185 | ||
186 | switch(pc) { | |
187 | case 'c': | |
188 | case 'C': | |
189 | Cave_man[2].trquan = 12 + rnd(9)*rnd(9); | |
190 | u.uhp = u.uhpmax = 16; | |
191 | u.ustr = u.ustrmax = 18; | |
192 | ini_inv(Cave_man); | |
193 | break; | |
194 | case 't': | |
195 | case 'T': | |
196 | Tourist[3].trquan = 20 + rnd(20); | |
197 | u.ugold = u.ugold0 = rnd(1000); | |
198 | u.uhp = u.uhpmax = 10; | |
199 | u.ustr = u.ustrmax = 8; | |
200 | ini_inv(Tourist); | |
201 | if(!rn2(25)) ini_inv(Tinopener); | |
202 | break; | |
203 | case 'w': | |
204 | case 'W': | |
205 | for(i=1; i<=4; i++) if(!rn2(5)) | |
206 | Wizard[i].trquan += rn2(3) - 1; | |
207 | u.uhp = u.uhpmax = 15; | |
208 | u.ustr = u.ustrmax = 16; | |
209 | ini_inv(Wizard); | |
210 | break; | |
211 | case 's': | |
212 | case 'S': | |
213 | Fast = INTRINSIC; | |
214 | Stealth = INTRINSIC; | |
215 | u.uhp = u.uhpmax = 12; | |
216 | u.ustr = u.ustrmax = 10; | |
217 | ini_inv(Speleologist); | |
218 | if(!rn2(10)) ini_inv(Tinopener); | |
219 | break; | |
220 | case 'k': | |
221 | case 'K': | |
222 | u.uhp = u.uhpmax = 12; | |
223 | u.ustr = u.ustrmax = 10; | |
224 | ini_inv(Knight); | |
225 | break; | |
226 | case 'f': | |
227 | case 'F': | |
228 | u.uhp = u.uhpmax = 14; | |
229 | u.ustr = u.ustrmax = 17; | |
230 | ini_inv(Fighter); | |
231 | break; | |
232 | default: /* impossible */ | |
233 | u.uhp = u.uhpmax = 12; | |
234 | u.ustr = u.ustrmax = 16; | |
235 | } | |
236 | find_ac(); | |
237 | if(!rn2(20)) { | |
238 | register int d = rn2(7) - 2; /* biased variation */ | |
239 | u.ustr += d; | |
240 | u.ustrmax += d; | |
241 | } | |
242 | ||
243 | #ifdef WIZARD | |
244 | if(wizard) wiz_inv(); | |
245 | #endif WIZARD | |
246 | ||
247 | /* make sure he can carry all he has - especially for T's */ | |
248 | while(inv_weight() > 0 && u.ustr < 118) | |
249 | u.ustr++, u.ustrmax++; | |
250 | } | |
251 | ||
252 | ini_inv(trop) register struct trobj *trop; { | |
253 | register struct obj *obj; | |
254 | extern struct obj *mkobj(); | |
255 | while(trop->trolet) { | |
256 | obj = mkobj(trop->trolet); | |
257 | obj->known = trop->trknown; | |
258 | /* not obj->dknown = 1; - let him look at it at least once */ | |
259 | obj->cursed = 0; | |
260 | if(obj->olet == WEAPON_SYM){ | |
261 | obj->quan = trop->trquan; | |
262 | trop->trquan = 1; | |
263 | } | |
264 | if(trop->trspe != UNDEF_SPE) | |
265 | obj->spe = trop->trspe; | |
266 | if(trop->trotyp != UNDEF_TYP) | |
267 | obj->otyp = trop->trotyp; | |
268 | else | |
269 | if(obj->otyp == WAN_WISHING) /* gitpyr!robert */ | |
270 | obj->otyp = WAN_DEATH; | |
271 | obj->owt = weight(obj); /* defined after setting otyp+quan */ | |
272 | obj = addinv(obj); | |
273 | if(obj->olet == ARMOR_SYM){ | |
274 | switch(obj->otyp){ | |
275 | case SHIELD: | |
276 | if(!uarms) setworn(obj, W_ARMS); | |
277 | break; | |
278 | case HELMET: | |
279 | if(!uarmh) setworn(obj, W_ARMH); | |
280 | break; | |
281 | case PAIR_OF_GLOVES: | |
282 | if(!uarmg) setworn(obj, W_ARMG); | |
283 | break; | |
284 | case ELVEN_CLOAK: | |
285 | if(!uarm2) | |
286 | setworn(obj, W_ARM); | |
287 | break; | |
288 | default: | |
289 | if(!uarm) setworn(obj, W_ARM); | |
290 | } | |
291 | } | |
292 | if(obj->olet == WEAPON_SYM) | |
293 | if(!uwep) setuwep(obj); | |
294 | #ifndef PYRAMID_BUG | |
295 | if(--trop->trquan) continue; /* make a similar object */ | |
296 | #else | |
297 | if(trop->trquan) { /* check if zero first */ | |
298 | --trop->trquan; | |
299 | if(trop->trquan) | |
300 | continue; /* make a similar object */ | |
301 | } | |
302 | #endif PYRAMID_BUG | |
303 | trop++; | |
304 | } | |
305 | } | |
306 | ||
307 | #ifdef WIZARD | |
308 | wiz_inv(){ | |
309 | register struct trobj *trop = &Extra_objs[0]; | |
310 | extern char *getenv(); | |
311 | register char *ep = getenv("INVENT"); | |
312 | register int type; | |
313 | while(ep && *ep) { | |
314 | type = atoi(ep); | |
315 | ep = index(ep, ','); | |
316 | if(ep) while(*ep == ',' || *ep == ' ') ep++; | |
317 | if(type <= 0 || type > NROFOBJECTS) continue; | |
318 | trop->trotyp = type; | |
319 | trop->trolet = objects[type].oc_olet; | |
320 | trop->trspe = 4; | |
321 | trop->trknown = 1; | |
322 | trop->trquan = 1; | |
323 | ini_inv(trop); | |
324 | } | |
325 | /* give him a wand of wishing by default */ | |
326 | trop->trotyp = WAN_WISHING; | |
327 | trop->trolet = WAND_SYM; | |
328 | trop->trspe = 20; | |
329 | trop->trknown = 1; | |
330 | trop->trquan = 1; | |
331 | ini_inv(trop); | |
332 | } | |
333 | #endif WIZARD | |
334 | ||
335 | plnamesuffix() { | |
336 | register char *p; | |
337 | if(p = rindex(plname, '-')) { | |
338 | *p = 0; | |
339 | pl_character[0] = p[1]; | |
340 | pl_character[1] = 0; | |
341 | if(!plname[0]) { | |
342 | askname(); | |
343 | plnamesuffix(); | |
344 | } | |
345 | } | |
346 | } | |
347 | ||
348 | role_index(pc) | |
349 | char pc; | |
350 | { /* must be called only from u_init() */ | |
351 | /* so that rolesyms[] is defined */ | |
352 | register char *cp; | |
353 | ||
354 | if(cp = index(rolesyms, pc)) | |
355 | return(cp - rolesyms); | |
356 | return(-1); | |
357 | } |