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