Wikihack
Advertisement

Below is the full text to botl.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/botl.c#line123]], for example.

The latest source code for vanilla NetHack is at Source code.


The NetHack General Public License applies to screenshots, source code and other content from NetHack.
1.    /*	SCCS Id: @(#)botl.c	3.4	1996/07/15	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    #ifdef OVL0
8.    extern const char *hu_stat[];	/* defined in eat.c */
9.    
10.   const char *hu_abbrev_stat[] = {	/* must be kept consistent with eat.c */
11.   	"Sat",
12.   	"",
13.   	"Hun",
14.   	"Wea",
15.   	"Ftg",
16.   	"Ftd",
17.   	"Sta"
18.   };
19.   
20.   const char * const enc_stat[] = {
21.   	"",
22.   	"Burdened",
23.   	"Stressed",
24.   	"Strained",
25.   	"Overtaxed",
26.   	"Overloaded"
27.   };
28.   
29.   const char *enc_abbrev_stat[] = {
30.   	"",
31.   	"Brd",
32.   	"Ssd",
33.   	"Snd",
34.   	"Otd",
35.   	"Old"
36.   };
37.   
38.   STATIC_DCL void NDECL(bot1);
39.   STATIC_DCL void NDECL(bot2);
40.   #ifdef ALLEG_FX
41.   STATIC_DCL void FDECL(set_botl_warn, (int));
42.   #endif
43.   #endif /* OVL0 */
44.   
45.   /* MAXCO must hold longest uncompressed status line, and must be larger
46.    * than COLNO
47.    *
48.    * longest practical second status line at the moment is
49.    *	Astral Plane $:12345 HP:700(700) Pw:111(111) AC:-127 Xp:30/123456789
50.    *      Wt:5000/1000 T:123456 Satiated Lev Conf FoodPois Ill Blind Stun Hallu
51.    *      Slime Held Overloaded
52.    * -- or somewhat over 160 characters
53.    */
54.   #if COLNO <= 170
55.   #define MAXCO 190
56.   #else
57.   #define MAXCO (COLNO+20)
58.   #endif
59.   
60.   #ifndef OVLB
61.   STATIC_DCL int mrank_sz;
62.   #else /* OVLB */
63.   STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
64.   #endif /* OVLB */
65.   
66.   STATIC_DCL const char *NDECL(rank);
67.   
68.   #ifdef OVL1
69.   
70.   #ifdef ALLEG_FX
71.   static int botl_warn = 0;
72.   
73.   static void
74.   set_botl_warn(level)
75.   int level;
76.   {
77.           botl_warn = level;
78.           flags.botl = 1;
79.   }
80.   #endif
81.   
82.   /* convert experience level (1..30) to rank index (0..8) */
83.   int
84.   xlev_to_rank(xlev)
85.   int xlev;
86.   {
87.   	return (xlev <= 2) ? 0 : (xlev <= 30) ? ((xlev + 2) / 4) : 8;
88.   }
89.   
90.   #if 0	/* not currently needed */
91.   /* convert rank index (0..8) to experience level (1..30) */
92.   int
93.   rank_to_xlev(rank)
94.   int rank;
95.   {
96.   	return (rank <= 0) ? 1 : (rank <= 8) ? ((rank * 4) - 2) : 30;
97.   }
98.   #endif
99.   
100.  const char *
101.  rank_of(lev, monnum, female)
102.  int lev;
103.  	short monnum;
104.  boolean female;
105.  {
106.  	register struct Role *role;
107.  	register int i;
108.  
109.  
110.  	/* Find the role */
111.  	for (role = (struct Role *) roles; role->name.m; role++)
112.  	    if (monnum == role->malenum || monnum == role->femalenum)
113.  	    	break;
114.  	if (!role->name.m)
115.  	    role = &urole;
116.  
117.  	/* Find the rank */
118.  	for (i = xlev_to_rank((int)lev); i >= 0; i--) {
119.  	    if (female && role->rank[i].f) return (role->rank[i].f);
120.  	    if (role->rank[i].m) return (role->rank[i].m);
121.  	}
122.  
123.  	/* Try the role name, instead */
124.  	if (female && role->name.f) return (role->name.f);
125.  	else if (role->name.m) return (role->name.m);
126.  	return ("Player");
127.  }
128.  
129.  
130.  STATIC_OVL const char *
131.  rank()
132.  {
133.  	return(rank_of(u.ulevel, Role_switch, flags.female));
134.  }
135.  
136.  int
137.  title_to_mon(str, rank_indx, title_length)
138.  const char *str;
139.  int *rank_indx, *title_length;
140.  {
141.  	register int i, j;
142.  
143.  
144.  	/* Loop through each of the roles */
145.  	for (i = 0; roles[i].name.m; i++)
146.  	    for (j = 0; j < 9; j++) {
147.  	    	if (roles[i].rank[j].m && !strncmpi(str,
148.  	    			roles[i].rank[j].m, strlen(roles[i].rank[j].m))) {
149.  	    	    if (rank_indx) *rank_indx = j;
150.  	    	    if (title_length) *title_length = strlen(roles[i].rank[j].m);
151.  	    	    return roles[i].malenum;
152.  	    	}
153.  	    	if (roles[i].rank[j].f && !strncmpi(str,
154.  	    			roles[i].rank[j].f, strlen(roles[i].rank[j].f))) {
155.  	    	    if (rank_indx) *rank_indx = j;
156.  	    	    if (title_length) *title_length = strlen(roles[i].rank[j].f);
157.  	    	    return ((roles[i].femalenum != NON_PM) ?
158.  	    	    		roles[i].femalenum : roles[i].malenum);
159.  	    	}
160.  	    }
161.  	return NON_PM;
162.  }
163.  
164.  #endif /* OVL1 */
165.  #ifdef OVLB
166.  
167.  void
168.  max_rank_sz()
169.  {
170.  	register int i, r, maxr = 0;
171.  
172.  
173.  	for (i = 0; i < 9; i++) {
174.  	    if (urole.rank[i].m && (r = strlen(urole.rank[i].m)) > maxr) maxr = r;
175.  	    if (urole.rank[i].f && (r = strlen(urole.rank[i].f)) > maxr) maxr = r;
176.  	}
177.  	mrank_sz = maxr;
178.  	return;
179.  }
180.  
181.  #endif /* OVLB */
182.  #ifdef OVL0
183.  
184.  #ifdef SCORE_ON_BOTL
185.  long
186.  botl_score()
187.  {
188.      int deepest = deepest_lev_reached(FALSE);
189.  #ifndef GOLDOBJ
190.      long ugold = u.ugold + hidden_gold();
191.  
192.      if ((ugold -= u.ugold0) < 0L) ugold = 0L;
193.      return ugold + u.urexp + (long)(50 * (deepest - 1))
194.  #else
195.      long umoney = money_cnt(invent) + hidden_gold();
196.  
197.      if ((umoney -= u.umoney0) < 0L) umoney = 0L;
198.      return umoney + u.urexp + (long)(50 * (deepest - 1))
199.  #endif
200.  			  + (long)(deepest > 30 ? 10000 :
201.  				   deepest > 20 ? 1000*(deepest - 20) : 0);
202.  }
203.  #endif
204.  
205.  static char *
206.  botl_player()
207.  {
208.      static char player[MAXCO];
209.  	register char *nb;
210.      char mbot[MAXCO - 15];
211.      int k = 0;
212.  
213.      Strcpy(player, plname);
214.      if ('a' <= player[0] && player[0] <= 'z') player[0] += 'A'-'a';
215.      player[10] = 0;
216.      Sprintf(nb = eos(player)," the ");
217.  
218.  	if (Upolyd) {
219.  	(void) strncpy(mbot, mons[u.umonnum].mname, SIZE(mbot) - 1);
220.  	mbot[SIZE(mbot) - 1] = 0;
221.  		while(mbot[k] != 0) {
222.  		    if ((k == 0 || (k > 0 && mbot[k-1] == ' ')) &&
223.  					'a' <= mbot[k] && mbot[k] <= 'z')
224.  			mbot[k] += 'A' - 'a';
225.  		    k++;
226.  		}
227.  	Sprintf(eos(nb), mbot);
228.  	} else
229.  	Sprintf(eos(nb), rank());
230.      return player;
231.  }
232.  
233.  static char *
234.  botl_strength()
235.  {
236.      static char strength[6];
237.  	if (ACURR(A_STR) > 18) {
238.  		if (ACURR(A_STR) > STR18(100))
239.  	    Sprintf(strength, "%2d", ACURR(A_STR)-100);
240.  		else if (ACURR(A_STR) < STR18(100))
241.  	    Sprintf(strength, "18/%02d", ACURR(A_STR)-18);
242.  		else
243.  	    Sprintf(strength, "18/**");
244.  	} else
245.  	Sprintf(strength, "%-1d", ACURR(A_STR));
246.      return strength;
247.  }
248.  
249.  STATIC_OVL void
250.  bot1()
251.  {
252.  	char newbot1[MAXCO];
253.  	register char *nb;
254.  	register int i,j;
255.  
256.  	Strcpy(newbot1, botl_player());
257.  	Sprintf(nb = eos(newbot1),"  ");
258.  	i = mrank_sz + 15;
259.  	j = (nb + 2) - newbot1; /* aka strlen(newbot1) but less computation */
260.  	if((i - j) > 0)
261.  		Sprintf(nb = eos(nb),"%*s", i-j, " ");  /* pad with spaces */
262.          
263.  	Sprintf(nb = eos(nb), "St:%s ", botl_strength());
264.  	Sprintf(nb = eos(nb),
265.  		"Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
266.  		ACURR(A_DEX), ACURR(A_CON), ACURR(A_INT), ACURR(A_WIS), ACURR(A_CHA));
267.  	Sprintf(nb = eos(nb), (u.ualign.type == A_CHAOTIC) ? "  Chaotic" :
268.  			(u.ualign.type == A_NEUTRAL) ? "  Neutral" : "  Lawful");
269.  #ifdef SCORE_ON_BOTL
270.  	if (flags.showscore)
271.  	    Sprintf(nb = eos(nb), " S:%ld", botl_score());
272.  #endif
273.  	curs(WIN_STATUS, 1, 0);
274.  	putstr(WIN_STATUS, 0, newbot1);
275.  }
276.  
277.  /* provide the name of the current level for display by various ports */
278.  int
279.  describe_level(buf, verbose)
280.  char *buf;
281.  int verbose;
282.  {
283.  	int ret = 1;
284.  
285.  	/* TODO:	Add in dungeon name */
286.  	if (Is_knox(&u.uz))
287.  		Sprintf(buf, "%s ", dungeons[u.uz.dnum].dname);
288.  	else if (In_quest(&u.uz))
289.  		Sprintf(buf, "Home %d ", dunlev(&u.uz));
290.  	else if (In_endgame(&u.uz))
291.  		Sprintf(buf,
292.  			Is_astralevel(&u.uz) ? "Astral Plane " : "End Game ");
293.  	else {
294.  		if (verbose)
295.  			Sprintf(buf, "%s, level %d ",
296.  				dungeons[u.uz.dnum].dname, depth(&u.uz));
297.  		else
298.  		Sprintf(buf, "Dlvl:%-2d ", depth(&u.uz));
299.  		ret = 0;
300.  	}
301.  	return ret;
302.  }
303.  
304.  /* [ALI] Line 2 abbreviation levels:
305.   *	0 - No abbreviation
306.   *	1 - Omit gold
307.   *	2 - Abbreviated status tags
308.   *	3 - Disable show options
309.   *	4 - Omit dungeon level
310.   *
311.   * We omit gold first since the '$' command is always available.
312.   *
313.   * While the abbreviated status tags are very difficult to interpret, we use
314.   * these before disabling the show options on the basis that the user always
315.   * has the choice of turning the show options off if that would be preferable.
316.   *
317.   * Last to go is the dungeon level on the basis that there is no way of
318.   * finding this information other than via the status line.
319.   */
320.  
321.  static int bot2_abbrev = 0;	/* Line 2 abbreviation level (max 4) */
322.  
323.  STATIC_OVL void
324.  bot2str(char *newbot2)
325.  {
326.  	register char *nb;
327.  	int hp, hpmax;
328.  	int cap = near_capacity();
329.  #ifdef ALLEG_FX
330.  	int w;
331.  #endif
332.  
333.  	hp = Upolyd ? u.mh : u.uhp;
334.  	hpmax = Upolyd ? u.mhmax : u.uhpmax;
335.  
336.  	if(hp < 0) hp = 0;
337.  	if (bot2_abbrev < 4)
338.  		(void) describe_level(newbot2, FALSE);
339.  	else
340.  		newbot2[0] = '\0';
341.  	if (bot2_abbrev < 1)
342.  		Sprintf(nb = eos(newbot2), "%c:%-2ld ",
343.  		  oc_syms[COIN_CLASS],
344.  #ifndef GOLDOBJ
345.  		u.ugold
346.  #else
347.  		money_cnt(invent)
348.  #endif
349.  		  );
350.  	else
351.  		nb = newbot2;
352.  	Sprintf(nb = eos(nb), "HP:%d(%d) Pw:%d(%d) AC:%-2d",
353.  		hp, hpmax, u.uen, u.uenmax, u.uac);
354.  
355.  	if (Upolyd)
356.  		Sprintf(nb = eos(nb), " HD:%d", ((u.ulycn == u.umonnum) ? 
357.  						u.ulevel : mons[u.umonnum].mlevel));
358.  #ifdef EXP_ON_BOTL
359.  	else if(flags.showexp && bot2_abbrev < 3)
360.  		Sprintf(nb = eos(nb), " Xp:%u/%-1ld", u.ulevel,u.uexp);
361.  #endif
362.  	else
363.  		Sprintf(nb = eos(nb), " Exp:%u", u.ulevel);
364.  
365.  #ifdef SHOW_WEIGHT
366.  	if (flags.showweight && bot2_abbrev < 3)
367.  		Sprintf(nb = eos(nb), "  Wt:%ld/%ld", (long)(inv_weight()+weight_cap()),
368.  				(long)weight_cap());
369.  #endif
370.  
371.  	if(flags.time && bot2_abbrev < 3)
372.  	        Sprintf(nb = eos(nb), "  T:%ld ", moves);
373.  
374.  #ifdef ALLEG_FX
375.          if(iflags.usealleg && botl_warn && !Hallucination)
376.          {
377.              Sprintf(nb = eos(nb), " ");
378.              for(w = 0; w < botl_warn; w++)
379.                  Sprintf(nb = eos(nb), "!");
380.          }
381.  #endif
382.  	        
383.          if (bot2_abbrev >= 2) {
384.  		if (hu_abbrev_stat[u.uhs][0]!='\0') {
385.  			Sprintf(nb = eos(nb), " ");
386.  			Strcat(newbot2, hu_abbrev_stat[u.uhs]);
387.  		}
388.  	}
389.  	else if(strcmp(hu_stat[u.uhs], "        ")) {
390.  		Sprintf(nb = eos(nb), " ");
391.  		Strcat(newbot2, hu_stat[u.uhs]);
392.  	}
393.  
394.  /* WAC further Up
395.  #ifdef SCORE_ON_BOTL
396.  	if (flags.showscore)
397.                  Sprintf(nb,"%c:%-2ld  Score:%ld", oc_syms[COIN_CLASS],
398.                     u.ugold, botl_score());
399.  #endif
400.  */
401.  	/* KMH -- changed to Lev */
402.  	if (Levitation)    Sprintf(nb = eos(nb), " Lev");
403.  	if(Confusion)
404.  		Sprintf(nb = eos(nb), bot2_abbrev >= 2 ? " Cnf" : " Conf");
405.  	if(Sick) {
406.  		if (u.usick_type & SICK_VOMITABLE)
407.  			   Sprintf(nb = eos(nb),
408.  			     bot2_abbrev >= 2 ? " FPs" : " FoodPois");
409.  		if (u.usick_type & SICK_NONVOMITABLE)
410.  			   Sprintf(nb = eos(nb), " Ill");
411.  	}
412.  
413.  	if(Blind)
414.  		Sprintf(nb = eos(nb), bot2_abbrev >= 2 ? " Bnd" : " Blind");
415.  	if(Stunned)
416.  		Sprintf(nb = eos(nb), bot2_abbrev >= 2 ? " Stn" : " Stun");
417.  	if(Hallucination)
418.  		Sprintf(nb = eos(nb), bot2_abbrev >= 2 ? " Hal" : " Hallu");
419.  	if(Slimed)
420.  		Sprintf(nb = eos(nb), bot2_abbrev >= 2 ? " Slm" : " Slime");
421.  	if(u.ustuck && !u.uswallow && !sticks(youmonst.data))
422.  		Sprintf(nb = eos(nb), " Held");
423.  	if(cap > UNENCUMBERED)
424.  		Sprintf(nb = eos(nb), " %s",
425.  		  bot2_abbrev >= 2 ? enc_abbrev_stat[cap] : enc_stat[cap]);
426.  }
427.  
428.  STATIC_OVL void
429.  bot2()
430.  {
431.  	char  newbot2[MAXCO];
432.  
433.  	bot2str(newbot2);
434.  	curs(WIN_STATUS, 1, 1);
435.  
436.  	putstr(WIN_STATUS, 0, newbot2);
437.  	return;
438.  }
439.  
440.  /* WAC -- Shorten bot1 to fit in len spaces.
441.   * Not currently used
442.   * Longest string past Str: is
443.   * ". Str:18/99 Dx:11 Co:13 In:12 Wi:14 Ch:14 Neutral" or 49 Chars long.
444.   */
445.  #if 0
446.  const char*
447.  shorten_bot1(str, len)
448.  const char *str;
449.  int len;
450.  {
451.      static char cbuf[BUFSZ];
452.  
453.      register const char *bp0 = str;
454.      register char *bp1 = cbuf;
455.      int k = 0;
456.  
457.      do {
458.              *bp1++ = *bp0;
459.              k++;
460.      } while(*bp0++ && k < (len - 49));
461.      
462.      cbuf[k] = '.';
463.      bp1++;
464.      
465.      bp0 = index(str, ':') - 3;
466.      do {
467.              *bp1++ = *bp0;
468.      } while(*bp0++);
469.      return cbuf;
470.  }
471.  #endif /* 0 */
472.  
473.  /* ALI -- Shorten bot2 to fit in len spaces.
474.   * Currently only used by tty port
475.   * After the forth attempt the longest practical bot2 becomes:
476.   *      HP:700(700) Pw:111(111) AC:-127 Exp:30
477.   *      Sat Lev Cnf FPs Ill Bnd Stn Hal Slm Old
478.   * -- or just under 80 characters
479.   */
480.  #ifdef TTY_GRAPHICS
481.  const char*
482.  shorten_bot2(str, len)
483.  const char *str;
484.  unsigned int len;
485.  {
486.      static char cbuf[MAXCO];
487.      for(bot2_abbrev = 1; bot2_abbrev <= 4; bot2_abbrev++) {
488.  	bot2str(cbuf);
489.  	if (strlen(cbuf) <= len)
490.  	    break;
491.      }
492.      if (bot2_abbrev > 4)
493.  	cbuf[len] = '\0';	/* If all else fails, truncate the line */
494.      bot2_abbrev = 0;
495.      return cbuf;
496.  }
497.  #endif /* TTY_GRAPHICS */
498.  
499.  static void (*raw_handler)();
500.  
501.  static void bot_raw(reconfig)
502.  boolean reconfig;
503.  {
504.      const char *botl_raw_values[24], **rv = botl_raw_values;
505.      char dex[3], con[3], itl[3], wis[3], cha[3], score[21];
506.      int uhp;
507.      char dlevel[BUFSZ];
508.      char hp[21], hpmax[21], pw[21], pwmax[21], gold[21], ac[21], elevel[21];
509.      char expr[21], iweight[21], capacity[21], flgs[21], tim[21];
510.      *rv++ = reconfig ? "player" : botl_player();
511.      *rv++ = reconfig ? "strength" : botl_strength();
512.      *rv++ = reconfig ? "dexterity" : (Sprintf(dex, "%d", ACURR(A_DEX)), dex);
513.      *rv++ = reconfig ? "constitution" : (Sprintf(con, "%d", ACURR(A_CON)), con);
514.      *rv++ = reconfig ? "intelligence" : (Sprintf(itl, "%d", ACURR(A_INT)), itl);
515.      *rv++ = reconfig ? "wisdom" : (Sprintf(wis, "%d", ACURR(A_WIS)), wis);
516.      *rv++ = reconfig ? "charisma" : (Sprintf(cha, "%d", ACURR(A_CHA)), cha);
517.      *rv++ = reconfig ? "alignment" : u.ualign.type == A_CHAOTIC ? "Chaotic" :
518.  	    u.ualign.type == A_NEUTRAL ? "Neutral" : "Lawful";
519.  #ifdef SCORE_ON_BOTL
520.      if (flags.showscore)
521.  	*rv++ = reconfig ? "score" :
522.  		(Sprintf(score, "%ld", botl_score()), score);
523.  #endif
524.      uhp = Upolyd ? u.mh : u.uhp;
525.      if (uhp < 0) uhp = 0;
526.      (void) describe_level(dlevel, TRUE);
527.      eos(dlevel)[-1] = 0;
528.      *rv++ = reconfig ? "dlevel" : dlevel;
529.      *rv++ = reconfig ? "gold" : (Sprintf(gold, "%ld",
530.  #ifndef GOLDOBJ
531.      u.ugold
532.  #else
533.  	money_cnt(invent)
534.  #endif
535.      ), gold);
536.      *rv++ = reconfig ? "hp" : (Sprintf(hp, "%d", uhp), hp);
537.      *rv++ = reconfig ? "hpmax" :
538.  	    (Sprintf(hpmax, "%d", Upolyd ? u.mhmax : u.uhpmax), hpmax);
539.      *rv++ = reconfig ? "pw" : (Sprintf(pw, "%d", u.uen), pw);
540.      *rv++ = reconfig ? "pwmax" : (Sprintf(pwmax, "%d", u.uenmax), pwmax);
541.      *rv++ = reconfig ? "ac" : (Sprintf(ac, "%d", u.uac), ac);
542.      Sprintf(elevel, "%u",
543.  	    Upolyd && u.ulycn != u.umonnum ? mons[u.umonnum].mlevel : u.ulevel);
544.      *rv++ = reconfig ? (Upolyd ? "hitdice" : "elevel") : elevel;
545.  #ifdef EXP_ON_BOTL
546.      if (flags.showexp)
547.  	*rv++ = reconfig ? "experience" : (Sprintf(expr, "%ld", u.uexp), expr);
548.  #endif
549.  #ifdef SHOW_WEIGHT
550.      if (flags.showweight) {
551.  	*rv++ = reconfig ? "weight" : (Sprintf(iweight,
552.  		"%ld", (long)(inv_weight() + weight_cap())), iweight);
553.  	*rv++ = reconfig ? "capacity" : (Sprintf(capacity,
554.  		"%ld", (long)weight_cap()), capacity);
555.      }
556.  #endif
557.      if (flags.time)
558.  	*rv++ = reconfig ? "time" : (Sprintf(tim, "%ld", moves), tim);
559.      *rv++ = reconfig ? "hunger" : strcmp(hu_stat[u.uhs], "        ") ?
560.  	    hu_stat[u.uhs] : "";
561.      *rv++ = reconfig ? "encumberance" : enc_stat[near_capacity()];
562.      *rv++ = reconfig ? "flags" : (Sprintf(flgs, "%lX",
563.          (Levitation ? RAW_STAT_LEVITATION : 0) |
564.  	(Confusion ? RAW_STAT_CONFUSION : 0) |
565.  	(Sick && (u.usick_type & SICK_VOMITABLE) ? RAW_STAT_FOODPOIS : 0) |
566.  	(Sick && (u.usick_type & SICK_NONVOMITABLE) ? RAW_STAT_ILL : 0) |
567.  	(Blind ? RAW_STAT_BLIND : 0) |
568.  	(Stunned ? RAW_STAT_STUNNED : 0) |
569.  	(Hallucination ? RAW_STAT_HALLUCINATION : 0) |
570.  	(Slimed ? RAW_STAT_SLIMED : 0)), flgs);
571.      (*raw_handler)(reconfig, rv - botl_raw_values, botl_raw_values);
572.  }
573.  
574.  void bot_reconfig()
575.  {
576.      if (raw_handler)
577.  	bot_raw(TRUE);
578.      flags.botl = 1;
579.  }
580.  
581.  void
582.  bot_set_handler(handler)
583.  void (*handler)();
584.  {
585.      raw_handler = handler;
586.      bot_reconfig();
587.  }
588.  
589.  void
590.  bot()
591.  {
592.  	/*
593.  	 * ALI: Cope with the fact that u_init may not have been
594.  	 * called yet. This happens if the player selection menus
595.  	 * are long enough to overwite the status line. In this
596.  	 * case we will be called when the menu is removed while
597.  	 * youmonst.data is still NULL.
598.  	 */
599.  	if (!youmonst.data)
600.  		return;
601.  	if (raw_handler)
602.  		bot_raw(FALSE);
603.  	else {
604.  	bot1();
605.  	bot2();
606.  	}
607.  	flags.botl = flags.botlx = 0;
608.  }
609.  
610.  #endif /* OVL0 */
611.  
612.  /*botl.c*/
Advertisement