Source:SLASH'EM 0.0.7E7F2/botl.c

From NetHackWiki
Jump to navigation Jump to search

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.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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*/