|
|
1.1 root 1: /* display.c Larn is copyrighted 1986 by Noah Morgan. */
2: #include "header.h"
3: #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
4:
5: static int minx,maxx,miny,maxy,k,m;
6: static char bot1f=0,bot2f=0,bot3f=0;
7: char always=0;
8: /*
9: bottomline()
10:
11: now for the bottom line of the display
12: */
13: bottomline()
14: { recalc(); bot1f=1; }
15: bottomhp()
16: { bot2f=1; }
17: bottomspell()
18: { bot3f=1; }
19: bottomdo()
20: {
21: if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
22: if (bot2f) { bot2f=0; bot_hpx(); }
23: if (bot3f) { bot3f=0; bot_spellx(); }
24: }
25:
26: bot_linex()
27: {
28: register int i;
29: if (cbak[SPELLS] <= -50 || (always))
30: {
31: cursor( 1,18);
32: if (c[SPELLMAX]>99) lprintf("Spells:%3d(%3d)",(long)c[SPELLS],(long)c[SPELLMAX]);
33: else lprintf("Spells:%3d(%2d) ",(long)c[SPELLS],(long)c[SPELLMAX]);
34: lprintf(" AC: %-3d WC: %-3d Level",(long)c[AC],(long)c[WCLASS]);
35: if (c[LEVEL]>99) lprintf("%3d",(long)c[LEVEL]);
36: else lprintf(" %-2d",(long)c[LEVEL]);
37: lprintf(" Exp: %-9d %s\n",(long)c[EXPERIENCE],class[c[LEVEL]-1]);
38: lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
39: (long)c[HP],(long)c[HPMAX],(long)(c[STRENGTH]+c[STREXTRA]),(long)c[INTELLIGENCE]);
40: lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
41: (long)c[WISDOM],(long)c[CONSTITUTION],(long)c[DEXTERITY],(long)c[CHARISMA]);
42:
43: if ((level==0) || (wizard)) c[TELEFLAG]=0;
44: if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
45: lprintf(" Gold: %-6d",(long)c[GOLD]);
46: always=1; botside();
47: c[TMP] = c[STRENGTH]+c[STREXTRA];
48: for (i=0; i<100; i++) cbak[i]=c[i];
49: return;
50: }
51:
52: botsub(makecode(SPELLS,8,18),"%3d");
53: if (c[SPELLMAX]>99) botsub(makecode(SPELLMAX,12,18),"%3d)");
54: else botsub(makecode(SPELLMAX,12,18),"%2d) ");
55: botsub(makecode(HP,5,19),"%3d");
56: botsub(makecode(HPMAX,9,19),"%3d");
57: botsub(makecode(AC,21,18),"%-3d");
58: botsub(makecode(WCLASS,30,18),"%-3d");
59: botsub(makecode(EXPERIENCE,49,18),"%-9d");
60: if (c[LEVEL] != cbak[LEVEL])
61: { cursor(59,18); lprcat(class[c[LEVEL]-1]); }
62: if (c[LEVEL]>99) botsub(makecode(LEVEL,40,18),"%3d");
63: else botsub(makecode(LEVEL,40,18)," %-2d");
64: c[TMP] = c[STRENGTH]+c[STREXTRA]; botsub(makecode(TMP,18,19),"%-2d");
65: botsub(makecode(INTELLIGENCE,25,19),"%-2d");
66: botsub(makecode(WISDOM,32,19),"%-2d");
67: botsub(makecode(CONSTITUTION,39,19),"%-2d");
68: botsub(makecode(DEXTERITY,46,19),"%-2d");
69: botsub(makecode(CHARISMA,53,19),"%-2d");
70: if ((level != cbak[CAVELEVEL]) || (c[TELEFLAG] != cbak[TELEFLAG]))
71: {
72: if ((level==0) || (wizard)) c[TELEFLAG]=0;
73: cbak[TELEFLAG] = c[TELEFLAG];
74: cbak[CAVELEVEL] = level; cursor(59,19);
75: if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
76: }
77: botsub(makecode(GOLD,69,19),"%-6d");
78: botside();
79: }
80:
81: /*
82: special subroutine to update only the gold number on the bottomlines
83: called from ogold()
84: */
85: bottomgold()
86: {
87: botsub(makecode(GOLD,69,19),"%-6d");
88: /* botsub(GOLD,"%-6d",69,19); */
89: }
90:
91: /*
92: special routine to update hp and level fields on bottom lines
93: called in monster.c hitplayer() and spattack()
94: */
95: bot_hpx()
96: {
97: if (c[EXPERIENCE] != cbak[EXPERIENCE])
98: {
99: recalc(); bot_linex();
100: }
101: else botsub(makecode(HP,5,19),"%3d");
102: }
103:
104: /*
105: special routine to update number of spells called from regen()
106: */
107: bot_spellx()
108: {
109: botsub(makecode(SPELLS,9,18),"%2d");
110: }
111:
112: /*
113: common subroutine for a more economical bottomline()
114: */
115: static struct bot_side_def
116: {
117: int typ;
118: char *string;
119: }
120: bot_data[] =
121: {
122: STEALTH,"stealth", UNDEADPRO,"undead pro", SPIRITPRO,"spirit pro",
123: CHARMCOUNT,"Charm", TIMESTOP,"Time Stop", HOLDMONST,"Hold Monst",
124: GIANTSTR,"Giant Str", FIRERESISTANCE,"Fire Resit", DEXCOUNT,"Dexterity",
125: STRCOUNT,"Strength", SCAREMONST,"Scare", HASTESELF,"Haste Self",
126: CANCELLATION,"Cancel", INVISIBILITY,"Invisible", ALTPRO,"Protect 3",
127: PROTECTIONTIME,"Protect 2", WTW,"Wall-Walk"
128: };
129:
130: botside()
131: {
132: register int i,idx;
133: for (i=0; i<17; i++)
134: {
135: idx = bot_data[i].typ;
136: if ((always) || (c[idx] != cbak[idx]))
137: {
138: if ((always) || (cbak[idx] == 0))
139: { if (c[idx]) { cursor(70,i+1); lprcat(bot_data[i].string); } } else
140: if (c[idx]==0) { cursor(70,i+1); lprcat(" "); }
141: cbak[idx]=c[idx];
142: }
143: }
144: always=0;
145: }
146:
147: static botsub(idx,str)
148: register int idx;
149: char *str;
150: {
151: register int x,y;
152: y = idx & 0xff; x = (idx>>8) & 0xff; idx >>= 16;
153: if (c[idx] != cbak[idx])
154: { cbak[idx]=c[idx]; cursor(x,y); lprintf(str,(long)c[idx]); }
155: }
156:
157: /*
158: * subroutine to draw only a section of the screen
159: * only the top section of the screen is updated. If entire lines are being
160: * drawn, then they will be cleared first.
161: */
162: int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
163: draws(xmin,xmax,ymin,ymax)
164: int xmin,xmax,ymin,ymax;
165: {
166: register int i,idx;
167: if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
168: {
169: if (ymin==0) cl_up(79,ymax);
170: else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
171: xmin = -1;
172: }
173: d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */
174: drawscreen();
175: if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
176: {
177: for (i=ymin; i<ymax; i++)
178: {
179: idx = bot_data[i].typ;
180: if (c[idx])
181: {
182: cursor(70,i+1); lprcat(bot_data[i].string);
183: }
184: cbak[idx]=c[idx];
185: }
186: }
187: }
188:
189: /*
190: drawscreen()
191:
192: subroutine to redraw the whole screen as the player knows it
193: */
194: char screen[MAXX][MAXY],d_flag; /* template for the screen */
195: drawscreen()
196: {
197: register int i,j,k;
198: int lastx,lasty; /* variables used to optimize the object printing */
199: if (d_xmin==0 && d_xmax==MAXX && d_ymin==0 && d_ymax==MAXY)
200: {
201: d_flag=1; clear(); /* clear the screen */
202: }
203: else
204: {
205: d_flag=0; cursor(1,1);
206: }
207: if (d_xmin<0)
208: d_xmin=0; /* d_xmin=-1 means display all without bottomline */
209:
210: for (i=d_ymin; i<d_ymax; i++)
211: for (j=d_xmin; j<d_xmax; j++)
212: if (know[j][i]==0) screen[j][i] = ' '; else
213: if (k=mitem[j][i]) screen[j][i] = monstnamelist[k]; else
214: if ((k=item[j][i])==OWALL) screen[j][i] = '#';
215: else screen[j][i] = ' ';
216:
217: for (i=d_ymin; i<d_ymax; i++)
218: {
219: j=d_xmin; while ((screen[j][i]==' ') && (j<d_xmax)) j++;
220: /* was m=0 */
221: if (j >= d_xmax) m=d_xmin; /* don't search backwards if blank line */
222: else
223: { /* search backwards for end of line */
224: m=d_xmax-1; while ((screen[m][i]==' ') && (m>d_xmin)) --m;
225: if (j<=m) cursor(j+1,i+1); else continue;
226: }
227: while (j <= m)
228: {
229: if (j <= m-3)
230: {
231: for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000;
232: if (k < 1000)
233: { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); }
234: }
235: lprc(screen[j++][i]);
236: }
237: }
238: setbold(); /* print out only bold objects now */
239:
240: for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
241: for (j=d_xmin; j<d_xmax; j++)
242: {
243: if (k=item[j][i])
244: if (k != OWALL)
245: if ((know[j][i]) && (mitem[j][i]==0))
246: if (objnamelist[k]!=' ')
247: {
248: if (lasty!=i+1 || lastx!=j)
249: cursor(lastx=j+1,lasty=i+1); else lastx++;
250: lprc(objnamelist[k]);
251: }
252: }
253:
254: resetbold(); if (d_flag) { always=1; botside(); always=1; bot_linex(); }
255: oldx=99;
256: d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
257: }
258:
259: /*
260: showcell(x,y)
261:
262: subroutine to display a cell location on the screen
263: */
264: showcell(x,y)
265: int x,y;
266: {
267: register int i,j,k,m;
268: if (c[BLINDCOUNT]) return; /* see nothing if blind */
269: if (c[AWARENESS]) { minx = x-3; maxx = x+3; miny = y-3; maxy = y+3; }
270: else { minx = x-1; maxx = x+1; miny = y-1; maxy = y+1; }
271:
272: if (minx < 0) minx=0; if (maxx > MAXX-1) maxx = MAXX-1;
273: if (miny < 0) miny=0; if (maxy > MAXY-1) maxy = MAXY-1;
274:
275: for (j=miny; j<=maxy; j++)
276: for (m=minx; m<=maxx; m++)
277: if (know[m][j]==0)
278: {
279: cursor(m+1,j+1);
280: x=maxx; while (know[x][j]) --x;
281: for (i=m; i<=x; i++)
282: {
283: if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]);
284: else switch(k=item[i][j])
285: {
286: case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
287: case OIVDARTRAP: case OIVTRAPDOOR:
288: lprc(objnamelist[k]); break;
289:
290: default: setbold(); lprc(objnamelist[k]); resetbold();
291: };
292: know[i][j]=1;
293: }
294: m = maxx;
295: }
296: }
297:
298: /*
299: this routine shows only the spot that is given it. the spaces around
300: these coordinated are not shown
301: used in godirect() in monster.c for missile weapons display
302: */
303: show1cell(x,y)
304: int x,y;
305: {
306: if (c[BLINDCOUNT]) return; /* see nothing if blind */
307: cursor(x+1,y+1);
308: if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]);
309: else switch(k=item[x][y])
310: {
311: case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
312: case OIVDARTRAP: case OIVTRAPDOOR:
313: lprc(objnamelist[k]); break;
314:
315: default: setbold(); lprc(objnamelist[k]); resetbold();
316: };
317: know[x][y]|=1; /* we end up knowing about it */
318: }
319:
320: /*
321: showplayer()
322:
323: subroutine to show where the player is on the screen
324: cursor values start from 1 up
325: */
326: showplayer()
327: {
328: cursor(playerx+1,playery+1);
329: oldx=playerx; oldy=playery;
330: }
331:
332: /*
333: moveplayer(dir)
334:
335: subroutine to move the player from one room to another
336: returns 0 if can't move in that direction or hit a monster or on an object
337: else returns 1
338: nomove is set to 1 to stop the next move (inadvertent monsters hitting
339: players when walking into walls) if player walks off screen or into wall
340: */
341: short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
342: short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
343: moveplayer(dir)
344: int dir; /* from = present room # direction = [1-north]
345: [2-east] [3-south] [4-west] [5-northeast]
346: [6-northwest] [7-southeast] [8-southwest]
347: if direction=0, don't move--just show where he is */
348: {
349: register int k,m,i,j;
350: if (c[CONFUSE]) if (c[LEVEL]<rnd(30)) dir=rund(9); /*if confused any dir*/
351: k = playerx + diroffx[dir]; m = playery + diroffy[dir];
352: if (k<0 || k>=MAXX || m<0 || m>=MAXY) { nomove=1; return(yrepcount = 0); }
353: i = item[k][m]; j = mitem[k][m];
354: if (i==OWALL && c[WTW]==0) { nomove=1; return(yrepcount = 0); } /* hit a wall */
355: if (k==33 && m==MAXY-1 && level==1)
356: {
357: newcavelevel(0); for (k=0; k<MAXX; k++) for (m=0; m<MAXY; m++)
358: if (item[k][m]==OENTRANCE)
359: { playerx=k; playery=m; positionplayer(); drawscreen(); return(0); }
360: }
361: if (j>0) { hitmonster(k,m); return(yrepcount = 0); } /* hit a monster*/
362: lastpx = playerx; lastpy = playery;
363: playerx = k; playery = m;
364: if (i && i!=OTRAPARROWIV && i!=OIVTELETRAP && i!=OIVDARTRAP && i!=OIVTRAPDOOR) return(yrepcount = 0); else return(1);
365: }
366:
367: /*
368: * function to show what magic items have been discovered thus far
369: * enter with -1 for just spells, anything else will give scrolls & potions
370: */
371: static int lincount,count;
372: seemagic(arg)
373: int arg;
374: {
375: register int i,number;
376: count = lincount = 0; nosignal=1;
377:
378: if (arg== -1) /* if display spells while casting one */
379: {
380: for (number=i=0; i<SPNUM; i++) if (spelknow[i]) number++;
381: number = (number+2)/3 + 4; /* # lines needed to display */
382: cl_up(79,number); cursor(1,1);
383: }
384: else
385: {
386: resetscroll(); clear();
387: }
388:
389: lprcat("The magic spells you have discovered thus far:\n\n");
390: for (i=0; i<SPNUM; i++)
391: if (spelknow[i])
392: { lprintf("%s %-20s ",spelcode[i],spelname[i]); seepage(); }
393:
394: if (arg== -1)
395: {
396: seepage(); more(); nosignal=0;
397: draws(0,MAXX,0,number); return;
398: }
399:
400: lincount += 3; if (count!=0) { count=2; seepage(); }
401:
402: lprcat("\nThe magic scrolls you have found to date are:\n\n");
403: count=0;
404: for (i=0; i<MAXSCROLL; i++)
405: if (scrollname[i][0])
406: if (scrollname[i][1]!=' ')
407: { lprintf("%-26s",&scrollname[i][1]); seepage(); }
408:
409: lincount += 3; if (count!=0) { count=2; seepage(); }
410:
411: lprcat("\nThe magic potions you have found to date are:\n\n");
412: count=0;
413: for (i=0; i<MAXPOTION; i++)
414: if (potionname[i][0])
415: if (potionname[i][1]!=' ')
416: { lprintf("%-26s",&potionname[i][1]); seepage(); }
417:
418: if (lincount!=0) more(); nosignal=0; setscroll(); drawscreen();
419: }
420:
421: /*
422: * subroutine to paginate the seemagic function
423: */
424: seepage()
425: {
426: if (++count==3)
427: {
428: lincount++; count=0; lprc('\n');
429: if (lincount>17) { lincount=0; more(); clear(); }
430: }
431: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.