1 /* display.c Larn is copyrighted 1986 by Noah Morgan. */
2 /* $FreeBSD: src/games/larn/display.c,v 1.4 1999/11/16 02:57:21 billf Exp $ */
3 /* $DragonFly: src/games/larn/display.c,v 1.2 2003/06/17 04:25:24 dillon Exp $ */
5 #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
7 static int minx,maxx,miny,maxy,k,m;
8 static char bot1f=0,bot2f=0,bot3f=0;
13 now for the bottom line of the display
16 { recalc(); bot1f=1; }
23 if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
24 if (bot2f) { bot2f=0; bot_hpx(); }
25 if (bot3f) { bot3f=0; bot_spellx(); }
33 if (cbak[SPELLS] <= -50 || (always))
36 if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]);
37 else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]);
38 lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]);
39 if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]);
40 else lprintf(" %-2d",(long)c[LEVEL]);
41 lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]);
42 lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
43 (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]);
44 lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
45 (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]);
47 if ((level==0) || (wizard)) c[TELEFLAG]=0;
48 if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
49 lprintf(" Gold: %-6d",(long)c[GOLD]);
51 c[TMP] = c[STRENGTH]+c[STREXTRA];
52 for (i=0; i<100; i++) cbak[i]=c[i];
56 botsub(makecode(SPELLS,8,18),"%3d");
57 if (c[SPELLMAX]>99) botsub(makecode(SPELLMAX,12,18),"%3d)");
58 else botsub(makecode(SPELLMAX,12,18),"%2d) ");
59 botsub(makecode(HP,5,19),"%3d");
60 botsub(makecode(HPMAX,9,19),"%3d");
61 botsub(makecode(AC,21,18),"%-3d");
62 botsub(makecode(WCLASS,30,18),"%-3d");
63 botsub(makecode(EXPERIENCE,49,18),"%-9d");
64 if (c[LEVEL] != cbak[LEVEL])
65 { cursor(59,18); lprcat(class[c[LEVEL]-1]); }
66 if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d");
67 else botsub(makecode(LEVEL,40,18)," %-2d");
68 c[TMP] = c[STRENGTH]+c[STREXTRA]; botsub(makecode(TMP,18,19),"%-2d");
69 botsub(makecode(INTELLIGENCE,25,19),"%-2d");
70 botsub(makecode(WISDOM,32,19),"%-2d");
71 botsub(makecode(CONSTITUTION,39,19),"%-2d");
72 botsub(makecode(DEXTERITY,46,19),"%-2d");
73 botsub(makecode(CHARISMA,53,19),"%-2d");
74 if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG]))
76 if ((level==0) || (wizard)) c[TELEFLAG]=0;
77 cbak[TELEFLAG] = c[TELEFLAG];
78 cbak[CAVELEVEL] = level; cursor(59,19);
79 if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
81 botsub(makecode(GOLD,69,19),"%-6d");
86 special subroutine to update only the gold number on the bottomlines
91 botsub(makecode(GOLD,69,19),"%-6d");
92 /* botsub(GOLD,"%-6d",69,19); */
96 special routine to update hp and level fields on bottom lines
97 called in monster.c hitplayer() and spattack()
101 if (c[EXPERIENCE] != cbak[EXPERIENCE])
103 recalc(); bot_linex();
105 else botsub(makecode(HP,5,19),"%3d");
109 special routine to update number of spells called from regen()
113 botsub(makecode(SPELLS,9,18),"%2d");
117 common subroutine for a more economical bottomline()
119 static struct bot_side_def
126 STEALTH,"stealth", UNDEADPRO,"undead pro", SPIRITPRO,"spirit pro",
127 CHARMCOUNT,"Charm", TIMESTOP,"Time Stop", HOLDMONST,"Hold Monst",
128 GIANTSTR,"Giant Str", FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity",
129 STRCOUNT,"Strength", SCAREMONST,"Scare", HASTESELF,"Haste Self",
130 CANCELLATION,"Cancel", INVISIBILITY,"Invisible", ALTPRO,"Protect 3",
131 PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk"
139 idx = bot_data[i].typ;
140 if ((always) || (c[idx] != cbak[idx]))
142 if ((always) || (cbak[idx] == 0))
143 { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else
144 if (c[idx]==0) { cursor(70,i+1); lprcat(" "); }
157 y = idx & 0xff; x = (idx>>8) & 0xff; idx >>= 16;
158 if (c[idx] != cbak[idx])
159 { cbak[idx]=c[idx]; cursor(x,y); lprintf(str,(long)c[idx]); }
163 * subroutine to draw only a section of the screen
164 * only the top section of the screen is updated. If entire lines are being
165 * drawn, then they will be cleared first.
167 int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
168 draws(xmin,xmax,ymin,ymax)
169 int xmin,xmax,ymin,ymax;
172 if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
174 if (ymin==0) cl_up(79,ymax);
175 else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
178 d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */
180 if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
182 for (i=ymin; i<ymax; i++)
184 idx = bot_data[i].typ;
187 cursor(70,i+1); lprcat(bot_data[i].string);
197 subroutine to redraw the whole screen as the player knows it
199 char screen[MAXX][MAXY],d_flag; /* template for the screen */
203 int lastx,lasty; /* variables used to optimize the object printing */
204 if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY)
206 d_flag=1; clear(); /* clear the screen */
210 d_flag=0; cursor(1,1);
213 d_xmin=0; /* d_xmin=-1 means display all without bottomline */
215 for (i=d_ymin; i<d_ymax; i++)
216 for (j=d_xmin; j<d_xmax; j++)
217 if (know[j][i]==0) screen[j][i] = ' '; else
218 if (k=mitem[j][i]) screen[j][i] = monstnamelist[k]; else
219 if ((k=item[j][i])==OWALL) screen[j][i] = '#';
220 else screen[j][i] = ' ';
222 for (i=d_ymin; i<d_ymax; i++)
224 j=d_xmin; while ((screen[j][i]==' ') && (j<d_xmax)) j++;
226 if (j >= d_xmax) m=d_xmin; /* don't search backwards if blank line */
228 { /* search backwards for end of line */
229 m=d_xmax-1; while ((screen[m][i]==' ') && (m>d_xmin)) --m;
230 if (j<=m) cursor(j+1,i+1); else continue;
236 for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000;
238 { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); }
240 lprc(screen[j++][i]);
243 setbold(); /* print out only bold objects now */
245 for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
246 for (j=d_xmin; j<d_xmax; j++)
250 if ((know[j][i]) && (mitem[j][i]==0))
251 if (objnamelist[k]!=' ')
253 if (lasty!=i+1 || lastx!=j)
254 cursor(lastx=j+1,lasty=i+1); else lastx++;
255 lprc(objnamelist[k]);
259 resetbold(); if (d_flag) { always=1; botside(); always=1; bot_linex(); }
261 d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
267 subroutine to display a cell location on the screen
273 if (c[BLINDCOUNT]) return; /* see nothing if blind */
274 if (c[AWARENESS]) { minx = x-3; maxx = x+3; miny = y-3; maxy = y+3; }
275 else { minx = x-1; maxx = x+1; miny = y-1; maxy = y+1; }
277 if (minx < 0) minx=0; if (maxx > MAXX-1) maxx = MAXX-1;
278 if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1;
280 for (j=miny; j<=maxy; j++)
281 for (m=minx; m<=maxx; m++)
285 x=maxx; while (know[x][j]) --x;
288 if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]);
289 else switch(k=item[i][j])
291 case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
292 case OIVDARTRAP: case OIVTRAPDOOR:
293 lprc(objnamelist[k]); break;
295 default: setbold(); lprc(objnamelist[k]); resetbold();
304 this routine shows only the spot that is given it. the spaces around
305 these coordinated are not shown
306 used in godirect() in monster.c for missile weapons display
311 if (c[BLINDCOUNT]) return; /* see nothing if blind */
313 if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]);
314 else switch(k=item[x][y])
316 case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
317 case OIVDARTRAP: case OIVTRAPDOOR:
318 lprc(objnamelist[k]); break;
320 default: setbold(); lprc(objnamelist[k]); resetbold();
322 know[x][y]|=1; /* we end up knowing about it */
328 subroutine to show where the player is on the screen
329 cursor values start from 1 up
333 cursor(playerx+1,playery+1);
334 oldx=playerx; oldy=playery;
340 subroutine to move the player from one room to another
341 returns 0 if can't move in that direction or hit a monster or on an object
343 nomove is set to 1 to stop the next move (inadvertent monsters hitting
344 players when walking into walls) if player walks off screen or into wall
346 short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
347 short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
349 int dir; /* from = present room # direction = [1-north]
350 [2-east] [3-south] [4-west] [5-northeast]
351 [6-northwest] [7-southeast] [8-southwest]
352 if direction=0, don't move--just show where he is */
355 if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
356 k = playerx + diroffx[dir]; m = playery + diroffy[dir];
357 if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
358 i = item[k][m]; j = mitem[k][m];
359 if (i==OWALL && c[WTW]==0) { nomove=1; return(yrepcount = 0); } /* hit a wall */
360 if (k==33 && m==MAXY-1 && level==1)
362 newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
363 if (item[k][m]==OENTRANCE)
364 { playerx=k; playery=m; positionplayer(); drawscreen(); return(0); }
366 if (j>0) { hitmonster(k,m); return(yrepcount = 0); } /* hit a monster*/
367 lastpx = playerx; lastpy = playery;
368 playerx = k; playery = m;
369 if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0); else return(1);
373 * function to show what magic items have been discovered thus far
374 * enter with -1 for just spells, anything else will give scrolls & potions
376 static int lincount,count;
381 count = lincount = 0; nosignal=1;
383 if (arg== -1) /* if display spells while casting one */
385 for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
386 number = (number+2)/3 + 4; /* # lines needed to display */
387 cl_up(79,number); cursor(1,1);
391 resetscroll(); clear();
394 lprcat("The magic spells you have discovered thus far:\n\n");
395 for (i=0; i<SPNUM; i++)
397 { lprintf("%s %-20s ",spelcode[i],spelname[i]); seepage(); }
401 seepage(); more(); nosignal=0;
402 draws(0,MAXX,0,number); return;
405 lincount += 3; if (count!=0) { count=2; seepage(); }
407 lprcat("\nThe magic scrolls you have found to date are:\n\n");
409 for (i=0; i<MAXSCROLL; i++)
410 if (scrollname[i][0])
411 if (scrollname[i][1]!=' ')
412 { lprintf("%-26s",&scrollname[i][1]); seepage(); }
414 lincount += 3; if (count!=0) { count=2; seepage(); }
416 lprcat("\nThe magic potions you have found to date are:\n\n");
418 for (i=0; i<MAXPOTION; i++)
419 if (potionname[i][0])
420 if (potionname[i][1]!=' ')
421 { lprintf("%-26s",&potionname[i][1]); seepage(); }
423 if (lincount!=0) more(); nosignal=0; setscroll(); drawscreen();
427 * subroutine to paginate the seemagic function
433 lincount++; count=0; lprc('\n');
434 if (lincount>17) { lincount=0; more(); clear(); }