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 $ */
4 #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
6 static int minx,maxx,miny,maxy,k,m;
7 static char bot1f=0,bot2f=0,bot3f=0;
12 now for the bottom line of the display
15 { recalc(); bot1f=1; }
22 if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
23 if (bot2f) { bot2f=0; bot_hpx(); }
24 if (bot3f) { bot3f=0; bot_spellx(); }
32 if (cbak[SPELLS] <= -50 || (always))
35 if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]);
36 else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]);
37 lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]);
38 if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]);
39 else lprintf(" %-2d",(long)c[LEVEL]);
40 lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]);
41 lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
42 (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]);
43 lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
44 (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]);
46 if ((level==0) || (wizard)) c[TELEFLAG]=0;
47 if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
48 lprintf(" Gold: %-6d",(long)c[GOLD]);
50 c[TMP] = c[STRENGTH]+c[STREXTRA];
51 for (i=0; i<100; i++) cbak[i]=c[i];
55 botsub(makecode(SPELLS,8,18),"%3d");
56 if (c[SPELLMAX]>99) botsub(makecode(SPELLMAX,12,18),"%3d)");
57 else botsub(makecode(SPELLMAX,12,18),"%2d) ");
58 botsub(makecode(HP,5,19),"%3d");
59 botsub(makecode(HPMAX,9,19),"%3d");
60 botsub(makecode(AC,21,18),"%-3d");
61 botsub(makecode(WCLASS,30,18),"%-3d");
62 botsub(makecode(EXPERIENCE,49,18),"%-9d");
63 if (c[LEVEL] != cbak[LEVEL])
64 { cursor(59,18); lprcat(class[c[LEVEL]-1]); }
65 if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d");
66 else botsub(makecode(LEVEL,40,18)," %-2d");
67 c[TMP] = c[STRENGTH]+c[STREXTRA]; botsub(makecode(TMP,18,19),"%-2d");
68 botsub(makecode(INTELLIGENCE,25,19),"%-2d");
69 botsub(makecode(WISDOM,32,19),"%-2d");
70 botsub(makecode(CONSTITUTION,39,19),"%-2d");
71 botsub(makecode(DEXTERITY,46,19),"%-2d");
72 botsub(makecode(CHARISMA,53,19),"%-2d");
73 if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG]))
75 if ((level==0) || (wizard)) c[TELEFLAG]=0;
76 cbak[TELEFLAG] = c[TELEFLAG];
77 cbak[CAVELEVEL] = level; cursor(59,19);
78 if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
80 botsub(makecode(GOLD,69,19),"%-6d");
85 special subroutine to update only the gold number on the bottomlines
90 botsub(makecode(GOLD,69,19),"%-6d");
91 /* botsub(GOLD,"%-6d",69,19); */
95 special routine to update hp and level fields on bottom lines
96 called in monster.c hitplayer() and spattack()
100 if (c[EXPERIENCE] != cbak[EXPERIENCE])
102 recalc(); bot_linex();
104 else botsub(makecode(HP,5,19),"%3d");
108 special routine to update number of spells called from regen()
112 botsub(makecode(SPELLS,9,18),"%2d");
116 common subroutine for a more economical bottomline()
118 static struct bot_side_def
125 STEALTH,"stealth", UNDEADPRO,"undead pro", SPIRITPRO,"spirit pro",
126 CHARMCOUNT,"Charm", TIMESTOP,"Time Stop", HOLDMONST,"Hold Monst",
127 GIANTSTR,"Giant Str", FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity",
128 STRCOUNT,"Strength", SCAREMONST,"Scare", HASTESELF,"Haste Self",
129 CANCELLATION,"Cancel", INVISIBILITY,"Invisible", ALTPRO,"Protect 3",
130 PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk"
138 idx = bot_data[i].typ;
139 if ((always) || (c[idx] != cbak[idx]))
141 if ((always) || (cbak[idx] == 0))
142 { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else
143 if (c[idx]==0) { cursor(70,i+1); lprcat(" "); }
156 y = idx & 0xff; x = (idx>>8) & 0xff; idx >>= 16;
157 if (c[idx] != cbak[idx])
158 { cbak[idx]=c[idx]; cursor(x,y); lprintf(str,(long)c[idx]); }
162 * subroutine to draw only a section of the screen
163 * only the top section of the screen is updated. If entire lines are being
164 * drawn, then they will be cleared first.
166 int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
167 draws(xmin,xmax,ymin,ymax)
168 int xmin,xmax,ymin,ymax;
171 if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
173 if (ymin==0) cl_up(79,ymax);
174 else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
177 d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */
179 if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
181 for (i=ymin; i<ymax; i++)
183 idx = bot_data[i].typ;
186 cursor(70,i+1); lprcat(bot_data[i].string);
196 subroutine to redraw the whole screen as the player knows it
198 char screen[MAXX][MAXY],d_flag; /* template for the screen */
202 int lastx,lasty; /* variables used to optimize the object printing */
203 if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY)
205 d_flag=1; clear(); /* clear the screen */
209 d_flag=0; cursor(1,1);
212 d_xmin=0; /* d_xmin=-1 means display all without bottomline */
214 for (i=d_ymin; i<d_ymax; i++)
215 for (j=d_xmin; j<d_xmax; j++)
216 if (know[j][i]==0) screen[j][i] = ' '; else
217 if (k=mitem[j][i]) screen[j][i] = monstnamelist[k]; else
218 if ((k=item[j][i])==OWALL) screen[j][i] = '#';
219 else screen[j][i] = ' ';
221 for (i=d_ymin; i<d_ymax; i++)
223 j=d_xmin; while ((screen[j][i]==' ') && (j<d_xmax)) j++;
225 if (j >= d_xmax) m=d_xmin; /* don't search backwards if blank line */
227 { /* search backwards for end of line */
228 m=d_xmax-1; while ((screen[m][i]==' ') && (m>d_xmin)) --m;
229 if (j<=m) cursor(j+1,i+1); else continue;
235 for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000;
237 { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); }
239 lprc(screen[j++][i]);
242 setbold(); /* print out only bold objects now */
244 for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
245 for (j=d_xmin; j<d_xmax; j++)
249 if ((know[j][i]) && (mitem[j][i]==0))
250 if (objnamelist[k]!=' ')
252 if (lasty!=i+1 || lastx!=j)
253 cursor(lastx=j+1,lasty=i+1); else lastx++;
254 lprc(objnamelist[k]);
258 resetbold(); if (d_flag) { always=1; botside(); always=1; bot_linex(); }
260 d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
266 subroutine to display a cell location on the screen
272 if (c[BLINDCOUNT]) return; /* see nothing if blind */
273 if (c[AWARENESS]) { minx = x-3; maxx = x+3; miny = y-3; maxy = y+3; }
274 else { minx = x-1; maxx = x+1; miny = y-1; maxy = y+1; }
276 if (minx < 0) minx=0; if (maxx > MAXX-1) maxx = MAXX-1;
277 if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1;
279 for (j=miny; j<=maxy; j++)
280 for (m=minx; m<=maxx; m++)
284 x=maxx; while (know[x][j]) --x;
287 if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]);
288 else switch(k=item[i][j])
290 case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
291 case OIVDARTRAP: case OIVTRAPDOOR:
292 lprc(objnamelist[k]); break;
294 default: setbold(); lprc(objnamelist[k]); resetbold();
303 this routine shows only the spot that is given it. the spaces around
304 these coordinated are not shown
305 used in godirect() in monster.c for missile weapons display
310 if (c[BLINDCOUNT]) return; /* see nothing if blind */
312 if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]);
313 else switch(k=item[x][y])
315 case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
316 case OIVDARTRAP: case OIVTRAPDOOR:
317 lprc(objnamelist[k]); break;
319 default: setbold(); lprc(objnamelist[k]); resetbold();
321 know[x][y]|=1; /* we end up knowing about it */
327 subroutine to show where the player is on the screen
328 cursor values start from 1 up
332 cursor(playerx+1,playery+1);
333 oldx=playerx; oldy=playery;
339 subroutine to move the player from one room to another
340 returns 0 if can't move in that direction or hit a monster or on an object
342 nomove is set to 1 to stop the next move (inadvertent monsters hitting
343 players when walking into walls) if player walks off screen or into wall
345 short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
346 short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
348 int dir; /* from = present room # direction = [1-north]
349 [2-east] [3-south] [4-west] [5-northeast]
350 [6-northwest] [7-southeast] [8-southwest]
351 if direction=0, don't move--just show where he is */
354 if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
355 k = playerx + diroffx[dir]; m = playery + diroffy[dir];
356 if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
357 i = item[k][m]; j = mitem[k][m];
358 if (i==OWALL && c[WTW]==0) { nomove=1; return(yrepcount = 0); } /* hit a wall */
359 if (k==33 && m==MAXY-1 && level==1)
361 newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
362 if (item[k][m]==OENTRANCE)
363 { playerx=k; playery=m; positionplayer(); drawscreen(); return(0); }
365 if (j>0) { hitmonster(k,m); return(yrepcount = 0); } /* hit a monster*/
366 lastpx = playerx; lastpy = playery;
367 playerx = k; playery = m;
368 if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0); else return(1);
372 * function to show what magic items have been discovered thus far
373 * enter with -1 for just spells, anything else will give scrolls & potions
375 static int lincount,count;
380 count = lincount = 0; nosignal=1;
382 if (arg== -1) /* if display spells while casting one */
384 for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
385 number = (number+2)/3 + 4; /* # lines needed to display */
386 cl_up(79,number); cursor(1,1);
390 resetscroll(); clear();
393 lprcat("The magic spells you have discovered thus far:\n\n");
394 for (i=0; i<SPNUM; i++)
396 { lprintf("%s %-20s ",spelcode[i],spelname[i]); seepage(); }
400 seepage(); more(); nosignal=0;
401 draws(0,MAXX,0,number); return;
404 lincount += 3; if (count!=0) { count=2; seepage(); }
406 lprcat("\nThe magic scrolls you have found to date are:\n\n");
408 for (i=0; i<MAXSCROLL; i++)
409 if (scrollname[i][0])
410 if (scrollname[i][1]!=' ')
411 { lprintf("%-26s",&scrollname[i][1]); seepage(); }
413 lincount += 3; if (count!=0) { count=2; seepage(); }
415 lprcat("\nThe magic potions you have found to date are:\n\n");
417 for (i=0; i<MAXPOTION; i++)
418 if (potionname[i][0])
419 if (potionname[i][1]!=' ')
420 { lprintf("%-26s",&potionname[i][1]); seepage(); }
422 if (lincount!=0) more(); nosignal=0; setscroll(); drawscreen();
426 * subroutine to paginate the seemagic function
432 lincount++; count=0; lprc('\n');
433 if (lincount>17) { lincount=0; more(); clear(); }