Wikihack
Advertisement

Below is the full text to u_init.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/u_init.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

Screenshots and source code from Hack are used under the CWI license.
1.    /*	SCCS Id: @(#)u_init.c	1.4	87/08/08
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* u_init.c - version 1.0.3   */
4.    
5.    #include <stdio.h>
6.    #include <signal.h>
7.    #include "hack.h"
8.    #ifdef GENIX
9.    #define	void	int
10.   #endif
11.   
12.   #define Strcpy	(void) strcpy
13.   #define	Strcat	(void) strcat
14.   #define	UNDEF_TYP	0
15.   #define	UNDEF_SPE	'\177'
16.   extern struct obj *addinv();
17.   extern char *eos();
18.   extern char plname[];
19.   
20.   struct you zerou;
21.   char pl_character[PL_CSIZ];
22.   char *(roles[]) = {	/* must all have distinct first letter */
23.   			/* roles[4] & [7] may be changed for females */
24.   	"Archeologist", "Tourist", "Fighter", "Knight", "Cave-man",
25.   #ifdef NEWCLASS
26.   	"Samurai", "Ninja", "Priest",
27.   #endif
28.   #ifdef KAA
29.   	"Valkyrie", "Elf", "Healer",
30.   #endif
31.   	"Wizard"
32.   };
33.   #define	NR_OF_ROLES	SIZE(roles)
34.   char rolesyms[NR_OF_ROLES + 1];		/* filled by u_init() */
35.   
36.   struct trobj {
37.   	uchar trotyp;
38.   	schar trspe;
39.   	char trolet;
40.   	Bitfield(trquan,6);
41.   	Bitfield(trknown,1);
42.   };
43.   
44.   #ifdef WIZARD
45.   struct trobj Extra_objs[] = {
46.   	{ 0, 0, 0, 0, 0 },
47.   	{ 0, 0, 0, 0, 0 }
48.   };
49.   #endif
50.   
51.   struct trobj Cave_man[] = {
52.   #ifdef KAA
53.   	{ CLUB, 1, WEAPON_SYM, 1, 1 },
54.   #else
55.   	{ MACE, 1, WEAPON_SYM, 1, 1 },
56.   #endif
57.   	{ BOW, 1, WEAPON_SYM, 1, 1 },
58.   	{ ARROW, 0, WEAPON_SYM, 25, 1 },	/* quan is variable */
59.   	{ LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
60.   	{ 0, 0, 0, 0, 0}
61.   };
62.   
63.   struct trobj Fighter[] = {
64.   	{ TWO_HANDED_SWORD, 0, WEAPON_SYM, 1, 1 },
65.   	{ RING_MAIL, 0, ARMOR_SYM, 1, 1 },
66.   	{ 0, 0, 0, 0, 0 }
67.   };
68.   
69.   struct trobj Knight[] = {
70.   	{ LONG_SWORD, 0, WEAPON_SYM, 1, 1 },
71.   	{ SPEAR, 2, WEAPON_SYM, 1, 1 },
72.   	{ RING_MAIL, 1, ARMOR_SYM, 1, 1 },
73.   	{ HELMET, 0, ARMOR_SYM, 1, 1 },
74.   	{ SHIELD, 0, ARMOR_SYM, 1, 1 },
75.   	{ PAIR_OF_GLOVES, 0, ARMOR_SYM, 1, 1 },
76.   	{ 0, 0, 0, 0, 0 }
77.   };
78.   
79.   #ifdef KAA
80.   struct trobj Elf[] = {
81.   	{ SHORT_SWORD, 0, WEAPON_SYM, 1, 1 },
82.   	{ BOW, 0, WEAPON_SYM, 1, 1 },
83.   	{ ARROW, 0, WEAPON_SYM, 25, 1 },
84.   	{ UNDEF_TYP, 0, ARMOR_SYM, 1, 1 },
85.   	{ 0, 0, 0, 0, 0 }
86.   };
87.   
88.   struct trobj Valkyrie[] = {
89.   	{ LONG_SWORD, 1, WEAPON_SYM, 1, 1 },
90.   	{ SHIELD, 3, ARMOR_SYM, 1, 1 },
91.   	{ FOOD_RATION, 0, FOOD_SYM, 1, 1 },
92.   	{ 0, 0, 0, 0, 0 }
93.   };
94.   
95.   struct trobj Healer[] = {
96.   	{ STETHOSCOPE, 0, TOOL_SYM, 1, 0 },
97.   	{ POT_HEALING, 0, POTION_SYM, 4, 0 },
98.   	{ POT_EXTRA_HEALING, 0, POTION_SYM, 4, 0 },
99.   	{ APPLE, 0, FOOD_SYM, 5, 0 },
100.  	{ 0, 0, 0, 0, 0}
101.  };
102.  #endif /* KAA /**/
103.  
104.  struct trobj Archeologist[] = {
105.  	{ STUDDED_LEATHER_ARMOR, 0, ARMOR_SYM, 1, 1 },
106.  	{ UNDEF_TYP, 0, POTION_SYM, 2, 0 },
107.  	{ FOOD_RATION, 0, FOOD_SYM, 3, 1 },
108.  	{ PICK_AXE, UNDEF_SPE, TOOL_SYM, 1, 0 },
109.  	{ ICE_BOX, 0, TOOL_SYM, 1, 0 },
110.  	{ 0, 0, 0, 0, 0}
111.  };
112.  
113.  struct trobj Tinopener[] = {
114.  	{ CAN_OPENER, 0, TOOL_SYM, 1, 1 },
115.  	{ 0, 0, 0, 0, 0 }
116.  };
117.  
118.  #ifdef MARKER
119.  struct trobj Magicmarker[] = {
120.  	{ MAGIC_MARKER, 50, TOOL_SYM, 1, 0 },
121.  	{ 0, 0, 0, 0, 0 }
122.  };
123.  #endif
124.  
125.  #ifdef WALKIES
126.  struct trobj Leash[] = {
127.  	{ LEASH, 0, CHAIN_SYM, 1, 0 },
128.  	{ 0, 0, 0, 0, 0 }
129.  };
130.  #endif
131.  
132.  struct trobj Tourist[] = {
133.  	{ UNDEF_TYP, 0, FOOD_SYM, 10, 1 },
134.  	{ POT_EXTRA_HEALING, 0, POTION_SYM, 2, 0 },
135.  	{ EXPENSIVE_CAMERA, 0, TOOL_SYM, 1, 1 },
136.  	{ DART, 2, WEAPON_SYM, 25, 1 },	/* quan is variable */
137.  	{ 0, 0, 0, 0, 0 }
138.  };
139.  
140.  struct trobj Wizard[] = {
141.  	{ ELVEN_CLOAK, 0, ARMOR_SYM, 1, 1 },
142.  	{ UNDEF_TYP, UNDEF_SPE, WAND_SYM, 2, 0 },
143.  	{ UNDEF_TYP, UNDEF_SPE, RING_SYM, 2, 0 },
144.  	{ UNDEF_TYP, UNDEF_SPE, POTION_SYM, 2, 0 },
145.  	{ UNDEF_TYP, UNDEF_SPE, SCROLL_SYM, 3, 0 },
146.  #ifdef SPELLS
147.  	{ UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 1, 0 },
148.  #endif
149.  	{ 0, 0, 0, 0, 0 }
150.  };
151.  
152.  #ifdef NEWCLASS
153.  struct	trobj	Samurai[] = {
154.  	{ KATANA, 0, WEAPON_SYM, 1, 1 },
155.  	{ BOW,    1, WEAPON_SYM, 1, 1 },
156.  	{ ARROW,  0, WEAPON_SYM, 25, 1 },	/* quan is variable */
157.  	{ SPLINT_MAIL, 0, ARMOR_SYM, 1, 1},
158.  	{ 0, 0, 0, 0, 0 }
159.  };
160.  
161.  struct	trobj	Ninja[] = {
162.  	{ KATANA, 0, WEAPON_SYM, 1, 1 },
163.  	{ SHURIKEN, 0, WEAPON_SYM, 25, 1 },	/* quan is variable */
164.  	{ LEATHER_ARMOR, 1, ARMOR_SYM, 1, 1},
165.  	{ 0, 0, 0, 0, 0 }
166.  };
167.  
168.  struct	trobj	Priest[] = {
169.  	{ CHAIN_MAIL, 0, ARMOR_SYM, 1, 1 },
170.  	{ SHIELD, 0, ARMOR_SYM, 1, 1 },
171.  	{ MACE, 1, WEAPON_SYM, 1, 1 },
172.  #ifdef SPELLS
173.  	{ UNDEF_TYP, UNDEF_SPE, SPBOOK_SYM, 2, 0 },
174.  #endif
175.  	{ 0, 0, 0, 0, 0 }
176.  };
177.  #endif /* NEWCLASS /**/
178.  
179.  u_init(){
180.  register int i;
181.  char exper = 'y', pc;
182.  extern char readchar();
183.  	if(flags.female)  {	/* should have been set in HACKOPTIONS */
184.  		roles[4] = "Cave-woman";
185.  #ifdef NEWCLASS
186.  		roles[7] = "Priestess";
187.  #endif
188.  	}
189.  	for(i = 0; i < NR_OF_ROLES; i++)
190.  		rolesyms[i] = roles[i][0];
191.  	rolesyms[i] = 0;
192.  
193.  	if(pc = pl_character[0]) {
194.  		if('a' <= pc && pc <= 'z') pc += 'A'-'a';
195.  		if((i = role_index(pc)) >= 0)
196.  			goto got_suffix;	/* implies experienced */
197.  		printf("\nUnknown role: %c\n", pc);
198.  		pl_character[0] = pc = 0;
199.  	}
200.  
201.  	printf("\nShall I pick a character for you (yes, no, or quit) ? [ynq] ");
202.  
203.  	while(!index("yYnNqQ", (exper = readchar())))	bell();
204.  
205.  	printf("%c\n", exper);		/* echo */
206.  
207.  	if (index("qQ", exper)) {
208.  		clearlocks();
209.  		settty((char *) 0);
210.  		exit(0);
211.  	}
212.  
213.  	if(index("Yy", exper)) {
214.  		exper = 0;
215.  		goto beginner;
216.  	}
217.  
218.  	printf("\n Tell me what kind of character you are:\n");
219.  	printf(" Are you");
220.  	for(i = 0; i < NR_OF_ROLES; i++) {
221.  		printf(" %s %s", index("AEIOU",roles[i][0]) ? "an" : "a", roles[i]);
222.  		if((((i + 1) % 4) == 0) && (i != NR_OF_ROLES -1)) printf(",\n\t");
223.  		else if(i < NR_OF_ROLES - 2)	printf(",");
224.  		if(i == NR_OF_ROLES - 2)	printf(" or");
225.  	}
226.  	printf("? [%s or q(quit)] ", rolesyms);
227.  
228.  	while(pc = readchar()) {
229.  		if (pc == 'q' || pc == 'Q') {
230.  
231.  			clearlocks();
232.  			settty((char *) 0);
233.  			exit(0);
234.  		}
235.  		if('a' <= pc && pc <= 'z') pc += 'A'-'a';
236.  		if((i = role_index(pc)) >= 0) {
237.  			printf("%c\n", pc);	/* echo */
238.  			(void) fflush(stdout);	/* should be seen */
239.  			break;
240.  		}
241.  		if(pc == '\n') break;
242.  		bell();
243.  	}
244.  	if(pc == '\n')	pc = 0;
245.  
246.  beginner:
247.  	if(!pc) {
248.  		i = rn2(NR_OF_ROLES);
249.  		pc = rolesyms[i];
250.  		printf("\nThis game you will be %s %s%s.\n",
251.  			(exper || index("AEIOU", roles[i][0])) ? "an" : "a",
252.  			exper ? "experienced " : "", roles[i]);
253.  		getret();
254.  		/* give him some feedback in case mklev takes much time */
255.  		(void) putchar('\n');
256.  		(void) fflush(stdout);
257.  	}
258.  	if(exper) {
259.  		roles[i][0] = pc;
260.  	}
261.  
262.  got_suffix:
263.  
264.  	(void) strncpy(pl_character, roles[i], PL_CSIZ-1);
265.  	pl_character[PL_CSIZ-1] = 0;
266.  	flags.beginner = 1;
267.  	u = zerou;
268.  	u.usym = '@';
269.  	u.ulevel = 1;
270.  #ifdef SPELLS
271.  	u.uen = u.uenmax = 1;
272.  #endif
273.  #ifdef PRAYERS
274.  	u.ublesscnt = 300;			/* no prayers just yet */
275.  	u.ublessed = 0;				/* not worthy yet */
276.  	u.ugangr   = 0;				/* gods not angry */
277.  #endif
278.  #ifdef KAA
279.  	u.mh = u.mhmax = u.umonnum = u.mtimedone = 0;
280.  #endif
281.  	init_uhunger();
282.  #ifdef QUEST
283.  	u.uhorizon = 6;
284.  #endif
285.  	uarm = uarm2 = uarmh = uarms = uarmg = uwep = uball = uchain =
286.  	uleft = uright = 0;
287.  #ifdef SPELLS
288.  	for (i = 0; i <= MAXSPELL; i++) spl_book[i].sp_id = NO_SPELL;
289.  #endif
290.  	switch(pc) {
291.  	case 'c':
292.  	case 'C':
293.  		Cave_man[2].trquan = 12 + rnd(9)*rnd(9);
294.  		u.uhp = u.uhpmax = 16;
295.  		u.ustr = u.ustrmax = 18;
296.  		ini_inv(Cave_man);
297.  		break;
298.  	case 't':
299.  	case 'T':
300.  #ifdef KAA
301.  		objects[POT_EXTRA_HEALING].oc_name_known=1;
302.  #endif
303.  		Tourist[3].trquan = 20 + rnd(20);
304.  		u.ugold = u.ugold0 = rnd(1000);
305.  		u.uhp = u.uhpmax = 10;
306.  		u.ustr = u.ustrmax = 8;
307.  		ini_inv(Tourist);
308.  		if(!rn2(25)) ini_inv(Tinopener);
309.  #ifdef MARKER
310.  		else if(!rn2(25)) ini_inv(Magicmarker);
311.  #endif
312.  #ifdef WALKIES
313.  		else if(!rn2(25)) ini_inv(Leash);
314.  #endif
315.  		break;
316.  	case 'w':
317.  	case 'W':
318.  		for(i=1; i<=4; i++) if(!rn2(5))
319.  			Wizard[i].trquan += rn2(3) - 1;
320.  		u.uhp = u.uhpmax = 15;
321.  		u.ustr = u.ustrmax = 16;
322.  #ifdef SPELLS
323.  		u.uen = u.uenmax += rn2(4);
324.  #endif
325.  		ini_inv(Wizard);
326.  #ifdef MARKER
327.  		if(!rn2(5)) ini_inv(Magicmarker);
328.  #endif
329.  		break;
330.  	case 'a':
331.  	case 'A':
332.  		Fast = INTRINSIC;
333.  		Stealth = INTRINSIC;
334.  		u.uhp = u.uhpmax = 12;
335.  		u.ustr = u.ustrmax = 10;
336.  		ini_inv(Archeologist);
337.  		if(!rn2(10)) ini_inv(Tinopener);
338.  #ifdef MARKER
339.  		else if(!rn2(10)) ini_inv(Magicmarker);
340.  #endif
341.  		break;
342.  #ifdef KAA
343.  	case 'e':
344.  	case 'E':
345.  		Elf[2].trquan = 15+rnd(20);
346.  		Elf[3].trotyp = (rn2(2) ? ELFIN_CHAIN_MAIL : ELVEN_CLOAK);
347.  		Fast = INTRINSIC;
348.  		HSee_invisible = INTRINSIC;
349.  		u.uhp = u.uhpmax = 16;
350.  		u.ustr = u.ustrmax = 16;
351.  		ini_inv(Elf);
352.  		break;
353.  	case 'v':
354.  	case 'V':
355.  		Stealth = INTRINSIC;
356.  		HCold_resistance = INTRINSIC;
357.  		flags.female = TRUE;
358.  		u.uhp = u.uhpmax = 16;
359.  		u.ustr = u.ustrmax = 17;
360.  		ini_inv(Valkyrie);
361.  		break;
362.  	case 'h':
363.  	case 'H':
364.  		objects[POT_HEALING].oc_name_known=1;
365.  		objects[POT_EXTRA_HEALING].oc_name_known=1;
366.  		HPoison_resistance = INTRINSIC;
367.  		u.uhp = u.uhpmax = 16;
368.  		u.ustr = u.ustrmax = 15;
369.  		ini_inv(Healer);
370.  		break;
371.  #endif
372.  	case 'k':
373.  	case 'K':
374.  		u.uhp = u.uhpmax = 12;
375.  		u.ustr = u.ustrmax = 10;
376.  		ini_inv(Knight);
377.  		break;
378.  	case 'f':
379.  	case 'F':
380.  		u.uhp = u.uhpmax = 14;
381.  		u.ustr = u.ustrmax = 17;
382.  		ini_inv(Fighter);
383.  		break;
384.  #ifdef NEWCLASS
385.  	case 's':
386.  	case 'S':
387.  		Fast = INTRINSIC;
388.  		u.uhp = u.uhpmax = 16;
389.  		u.ustr = u.ustrmax = 16;
390.  		Samurai[2].trquan = 12 + rnd(9)*rnd(9);
391.  		ini_inv(Samurai);
392.  		break;
393.  	case 'n':
394.  	case 'N':
395.  		Fast = INTRINSIC;
396.  		Stealth = INTRINSIC;
397.  		u.uhp = u.uhpmax = 15;
398.  		u.ustr = u.ustrmax = 10;
399.  		Ninja[1].trquan = 12 + rnd(9)*rnd(9);
400.  		ini_inv(Ninja);
401.  		break;
402.  	case 'p':
403.  	case 'P':
404.  		u.uhp = u.uhpmax = 13;
405.  		u.ustr = u.ustrmax = 15;
406.  # ifdef SPELLS
407.  		u.uen = u.uenmax += rn2(4);
408.  # endif
409.  		ini_inv(Priest);
410.  # ifdef KAA
411.  		uwep->dknown = 1;	/* bless his primary weapon */
412.  # endif
413.  # ifdef MARKER
414.  		if(!rn2(10)) ini_inv(Magicmarker);
415.  # endif
416.  		break;
417.  #endif /* NEWCLASS /**/
418.  	default:	/* impossible */
419.  		u.uhp = u.uhpmax = 12;
420.  		u.ustr = u.ustrmax = 16;
421.  	}
422.  	find_ac();
423.  	if(!rn2(20)) {
424.  		register int d = rn2(7) - 2;	/* biased variation */
425.  		u.ustr += d;
426.  		u.ustrmax += d;
427.  	}
428.  
429.  #ifdef WIZARD
430.  	if(wizard) wiz_inv();
431.  #endif
432.  
433.  	/* make sure he can carry all he has - especially for T's */
434.  	while(inv_weight() > 0 && u.ustr < 118)
435.  		u.ustr++, u.ustrmax++;
436.  }
437.  
438.  ini_inv(trop) register struct trobj *trop; {
439.  register struct obj *obj;
440.  extern struct obj *mkobj();
441.  	while(trop->trolet) {
442.  		obj = mkobj(trop->trolet);
443.  		obj->known = trop->trknown;
444.  		/* not obj->dknown = 1; - let him look at it at least once */
445.  		obj->cursed = 0;
446.  		if(obj->olet == WEAPON_SYM){
447.  			obj->quan = trop->trquan;
448.  			trop->trquan = 1;
449.  		}
450.  		if(trop->trspe != UNDEF_SPE)
451.  			obj->spe = trop->trspe;
452.  		if(trop->trotyp != UNDEF_TYP)
453.  			obj->otyp = trop->trotyp;
454.  		else
455.  			if(obj->otyp == WAN_WISHING)	/* gitpyr!robert */
456.  				obj->otyp = WAN_DEATH;
457.  		obj->owt = weight(obj);	/* defined after setting otyp+quan */
458.  		obj = addinv(obj);
459.  		if(obj->olet == ARMOR_SYM){
460.  			switch(obj->otyp){
461.  			case SHIELD:
462.  				if(!uarms) setworn(obj, W_ARMS);
463.  				break;
464.  			case HELMET:
465.  				if(!uarmh) setworn(obj, W_ARMH);
466.  				break;
467.  			case PAIR_OF_GLOVES:
468.  				if(!uarmg) setworn(obj, W_ARMG);
469.  				break;
470.  			case ELVEN_CLOAK:
471.  				if(!uarm2)
472.  					setworn(obj, W_ARM);
473.  				break;
474.  			default:
475.  				if(!uarm) setworn(obj, W_ARM);
476.  			}
477.  		}
478.  		/* below changed by GAN 01/09/87 to allow wielding of
479.  		 * pick-axe or can-opener if there is no weapon
480.  		 */
481.  		if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
482.  		   obj->otyp == CAN_OPENER)
483.  			if(!uwep) setuwep(obj);
484.  #ifndef PYRAMID_BUG
485.  		if(--trop->trquan) continue;	/* make a similar object */
486.  #else
487.  		if(trop->trquan) {		/* check if zero first */
488.  			--trop->trquan;
489.  			if(trop->trquan)
490.  				continue;	/* make a similar object */
491.  		}
492.  #endif
493.  		trop++;
494.  	}
495.  }
496.  
497.  #ifdef WIZARD
498.  wiz_inv(){
499.  register struct trobj *trop = &Extra_objs[0];
500.  extern char *getenv();
501.  register char *ep = getenv("INVENT");
502.  register int type;
503.  	while(ep && *ep) {
504.  		type = atoi(ep);
505.  		ep = index(ep, ',');
506.  		if(ep) while(*ep == ',' || *ep == ' ') ep++;
507.  		if(type <= 0 || type > NROFOBJECTS) continue;
508.  		trop->trotyp = type;
509.  		trop->trolet = objects[type].oc_olet;
510.  		trop->trspe = 4;
511.  		trop->trknown = 1;
512.  		trop->trquan = 1;
513.  		ini_inv(trop);
514.  	}
515.  	/* give him a wand of wishing by default */
516.  	trop->trotyp = WAN_WISHING;
517.  	trop->trolet = WAND_SYM;
518.  	trop->trspe = 20;
519.  	trop->trknown = 1;
520.  	trop->trquan = 1;
521.  	ini_inv(trop);
522.  }
523.  #endif /* WIZARD /**/
524.  
525.  plnamesuffix() {
526.  register char *p;
527.  	if(p = rindex(plname, '-')) {
528.  		*p = 0;
529.  		pl_character[0] = p[1];
530.  		pl_character[1] = 0;
531.  		if(!plname[0]) {
532.  			askname();
533.  			plnamesuffix();
534.  		}
535.  	}
536.  }
537.  
538.  role_index(pc)
539.  char pc;
540.  {		/* must be called only from u_init() */
541.  		/* so that rolesyms[] is defined */
542.  	register char *cp;
543.  
544.  	if(cp = index(rolesyms, pc))
545.  		return(cp - rolesyms);
546.  	return(-1);
547.  }
Advertisement