Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / games / larn / display.c
... / ...
CommitLineData
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 $ */
4#include "header.h"
5#define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
6
7static int minx,maxx,miny,maxy,k,m;
8static char bot1f=0,bot2f=0,bot3f=0;
9char always=0;
10/*
11 bottomline()
12
13 now for the bottom line of the display
14 */
15bottomline()
16 { recalc(); bot1f=1; }
17bottomhp()
18 { bot2f=1; }
19bottomspell()
20 { bot3f=1; }
21bottomdo()
22 {
23 if (bot1f) { bot3f=bot1f=bot2f=0; bot_linex(); return; }
24 if (bot2f) { bot2f=0; bot_hpx(); }
25 if (bot3f) { bot3f=0; bot_spellx(); }
26 }
27
28static void botsub();
29
30bot_linex()
31 {
32 int i;
33 if (cbak[SPELLS] <= -50 || (always))
34 {
35 cursor( 1,18);
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]);
46
47 if ((level==0) || (wizard)) c[TELEFLAG]=0;
48 if (c[TELEFLAG]) lprcat(" ?"); else lprcat(levelname[level]);
49 lprintf(" Gold: %-6d",(long)c[GOLD]);
50 always=1; botside();
51 c[TMP] = c[STRENGTH]+c[STREXTRA];
52 for (i=0; i<100; i++) cbak[i]=c[i];
53 return;
54 }
55
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]))
75 {
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]);
80 }
81 botsub(makecode(GOLD,69,19),"%-6d");
82 botside();
83 }
84
85/*
86 special subroutine to update only the gold number on the bottomlines
87 called from ogold()
88 */
89bottomgold()
90 {
91 botsub(makecode(GOLD,69,19),"%-6d");
92/* botsub(GOLD,"%-6d",69,19); */
93 }
94
95/*
96 special routine to update hp and level fields on bottom lines
97 called in monster.c hitplayer() and spattack()
98 */
99bot_hpx()
100 {
101 if (c[EXPERIENCE] != cbak[EXPERIENCE])
102 {
103 recalc(); bot_linex();
104 }
105 else botsub(makecode(HP,5,19),"%3d");
106 }
107
108/*
109 special routine to update number of spells called from regen()
110 */
111bot_spellx()
112 {
113 botsub(makecode(SPELLS,9,18),"%2d");
114 }
115
116/*
117 common subroutine for a more economical bottomline()
118 */
119static struct bot_side_def
120 {
121 int typ;
122 char *string;
123 }
124 bot_data[] =
125 {
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"
132 };
133
134botside()
135 {
136 int i,idx;
137 for (i=0; i<17; i++)
138 {
139 idx = bot_data[i].typ;
140 if ((always) || (c[idx] != cbak[idx]))
141 {
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(" "); }
145 cbak[idx]=c[idx];
146 }
147 }
148 always=0;
149 }
150
151static void
152botsub(idx,str)
153 int idx;
154 char *str;
155 {
156 int x,y;
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]); }
160 }
161
162/*
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.
166 */
167int d_xmin=0,d_xmax=MAXX,d_ymin=0,d_ymax=MAXY; /* for limited screen drawing */
168draws(xmin,xmax,ymin,ymax)
169 int xmin,xmax,ymin,ymax;
170 {
171 int i,idx;
172 if (xmin==0 && xmax==MAXX) /* clear section of screen as needed */
173 {
174 if (ymin==0) cl_up(79,ymax);
175 else for (i=ymin; i<ymin; i++) cl_line(1,i+1);
176 xmin = -1;
177 }
178 d_xmin=xmin; d_xmax=xmax; d_ymin=ymin; d_ymax=ymax; /* for limited screen drawing */
179 drawscreen();
180 if (xmin<=0 && xmax==MAXX) /* draw stuff on right side of screen as needed*/
181 {
182 for (i=ymin; i<ymax; i++)
183 {
184 idx = bot_data[i].typ;
185 if (c[idx])
186 {
187 cursor(70,i+1); lprcat(bot_data[i].string);
188 }
189 cbak[idx]=c[idx];
190 }
191 }
192 }
193
194/*
195 drawscreen()
196
197 subroutine to redraw the whole screen as the player knows it
198 */
199char screen[MAXX][MAXY],d_flag; /* template for the screen */
200drawscreen()
201 {
202 int i,j,k;
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)
205 {
206 d_flag=1; clear(); /* clear the screen */
207 }
208 else
209 {
210 d_flag=0; cursor(1,1);
211 }
212 if (d_xmin<0)
213 d_xmin=0; /* d_xmin=-1 means display all without bottomline */
214
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] = ' ';
221
222 for (i=d_ymin; i<d_ymax; i++)
223 {
224 j=d_xmin; while ((screen[j][i]==' ') && (j<d_xmax)) j++;
225 /* was m=0 */
226 if (j >= d_xmax) m=d_xmin; /* don't search backwards if blank line */
227 else
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;
231 }
232 while (j <= m)
233 {
234 if (j <= m-3)
235 {
236 for (k=j; k<=j+3; k++) if (screen[k][i] != ' ') k=1000;
237 if (k < 1000)
238 { while(screen[j][i]==' ' && j<=m) j++; cursor(j+1,i+1); }
239 }
240 lprc(screen[j++][i]);
241 }
242 }
243 setbold(); /* print out only bold objects now */
244
245 for (lastx=lasty=127, i=d_ymin; i<d_ymax; i++)
246 for (j=d_xmin; j<d_xmax; j++)
247 {
248 if (k=item[j][i])
249 if (k != OWALL)
250 if ((know[j][i]) && (mitem[j][i]==0))
251 if (objnamelist[k]!=' ')
252 {
253 if (lasty!=i+1 || lastx!=j)
254 cursor(lastx=j+1,lasty=i+1); else lastx++;
255 lprc(objnamelist[k]);
256 }
257 }
258
259 resetbold(); if (d_flag) { always=1; botside(); always=1; bot_linex(); }
260 oldx=99;
261 d_xmin = 0 , d_xmax = MAXX , d_ymin = 0 , d_ymax = MAXY; /* for limited screen drawing */
262 }
263\f
264/*
265 showcell(x,y)
266
267 subroutine to display a cell location on the screen
268 */
269showcell(x,y)
270 int x,y;
271 {
272 int i,j,k,m;
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; }
276
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;
279
280 for (j=miny; j<=maxy; j++)
281 for (m=minx; m<=maxx; m++)
282 if (know[m][j]==0)
283 {
284 cursor(m+1,j+1);
285 x=maxx; while (know[x][j]) --x;
286 for (i=m; i<=x; i++)
287 {
288 if ((k=mitem[i][j]) != 0) lprc(monstnamelist[k]);
289 else switch(k=item[i][j])
290 {
291 case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
292 case OIVDARTRAP: case OIVTRAPDOOR:
293 lprc(objnamelist[k]); break;
294
295 default: setbold(); lprc(objnamelist[k]); resetbold();
296 };
297 know[i][j]=1;
298 }
299 m = maxx;
300 }
301 }
302
303/*
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
307 */
308show1cell(x,y)
309 int x,y;
310 {
311 if (c[BLINDCOUNT]) return; /* see nothing if blind */
312 cursor(x+1,y+1);
313 if ((k=mitem[x][y]) != 0) lprc(monstnamelist[k]);
314 else switch(k=item[x][y])
315 {
316 case OWALL: case 0: case OIVTELETRAP: case OTRAPARROWIV:
317 case OIVDARTRAP: case OIVTRAPDOOR:
318 lprc(objnamelist[k]); break;
319
320 default: setbold(); lprc(objnamelist[k]); resetbold();
321 };
322 know[x][y]|=1; /* we end up knowing about it */
323 }
324
325/*
326 showplayer()
327
328 subroutine to show where the player is on the screen
329 cursor values start from 1 up
330 */
331showplayer()
332 {
333 cursor(playerx+1,playery+1);
334 oldx=playerx; oldy=playery;
335 }
336
337/*
338 moveplayer(dir)
339
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
342 else returns 1
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
345 */
346short diroffx[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
347short diroffy[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
348moveplayer(dir)
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 */
353 {
354 int k,m,i,j;
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)
361 {
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); }
365 }
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);
370 }
371\f
372/*
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
375 */
376static int lincount,count;
377seemagic(arg)
378 int arg;
379 {
380 int i,number;
381 count = lincount = 0; nosignal=1;
382
383 if (arg== -1) /* if display spells while casting one */
384 {
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);
388 }
389 else
390 {
391 resetscroll(); clear();
392 }
393
394 lprcat("The magic spells you have discovered thus far:\n\n");
395 for (i=0; i<SPNUM; i++)
396 if (spelknow[i])
397 { lprintf("%s %-20s ",spelcode[i],spelname[i]); seepage(); }
398
399 if (arg== -1)
400 {
401 seepage(); more(); nosignal=0;
402 draws(0,MAXX,0,number); return;
403 }
404
405 lincount += 3; if (count!=0) { count=2; seepage(); }
406
407 lprcat("\nThe magic scrolls you have found to date are:\n\n");
408 count=0;
409 for (i=0; i<MAXSCROLL; i++)
410 if (scrollname[i][0])
411 if (scrollname[i][1]!=' ')
412 { lprintf("%-26s",&scrollname[i][1]); seepage(); }
413
414 lincount += 3; if (count!=0) { count=2; seepage(); }
415
416 lprcat("\nThe magic potions you have found to date are:\n\n");
417 count=0;
418 for (i=0; i<MAXPOTION; i++)
419 if (potionname[i][0])
420 if (potionname[i][1]!=' ')
421 { lprintf("%-26s",&potionname[i][1]); seepage(); }
422
423 if (lincount!=0) more(); nosignal=0; setscroll(); drawscreen();
424 }
425
426/*
427 * subroutine to paginate the seemagic function
428 */
429seepage()
430 {
431 if (++count==3)
432 {
433 lincount++; count=0; lprc('\n');
434 if (lincount>17) { lincount=0; more(); clear(); }
435 }
436 }