]>
git.cameronkatri.com Git - bsdgames-darwin.git/blob - larn/display.c
1 /* display.c Larn is copyrighted 1986 by Noah Morgan. */
3 #define makecode(_a,_b,_c) (((_a)<<16) + ((_b)<<8) + (_c))
5 static int minx
,maxx
,miny
,maxy
,k
,m
;
6 static char bot1f
=0,bot2f
=0,bot3f
=0;
11 now for the bottom line of the display
14 { recalc(); bot1f
=1; }
21 if (bot1f
) { bot3f
=bot1f
=bot2f
=0; bot_linex(); return; }
22 if (bot2f
) { bot2f
=0; bot_hpx(); }
23 if (bot3f
) { bot3f
=0; bot_spellx(); }
31 if (cbak
[SPELLS
] <= -50 || (always
))
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
]);
45 if ((level
==0) || (wizard
)) c
[TELEFLAG
]=0;
46 if (c
[TELEFLAG
]) lprcat(" ?"); else lprcat(levelname
[level
]);
47 lprintf(" Gold: %-6d",(long)c
[GOLD
]);
49 c
[TMP
] = c
[STRENGTH
]+c
[STREXTRA
];
50 for (i
=0; i
<100; i
++) cbak
[i
]=c
[i
];
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
]))
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
]);
79 botsub(makecode(GOLD
,69,19),"%-6d");
84 special subroutine to update only the gold number on the bottomlines
89 botsub(makecode(GOLD
,69,19),"%-6d");
90 /* botsub(GOLD,"%-6d",69,19); */
94 special routine to update hp and level fields on bottom lines
95 called in monster.c hitplayer() and spattack()
99 if (c
[EXPERIENCE
] != cbak
[EXPERIENCE
])
101 recalc(); bot_linex();
103 else botsub(makecode(HP
,5,19),"%3d");
107 special routine to update number of spells called from regen()
111 botsub(makecode(SPELLS
,9,18),"%2d");
115 common subroutine for a more economical bottomline()
117 static struct bot_side_def
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"
137 idx
= bot_data
[i
].typ
;
138 if ((always
) || (c
[idx
] != cbak
[idx
]))
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(" "); }
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
]); }
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.
165 int d_xmin
=0,d_xmax
=MAXX
,d_ymin
=0,d_ymax
=MAXY
; /* for limited screen drawing */
166 draws(xmin
,xmax
,ymin
,ymax
)
167 int xmin
,xmax
,ymin
,ymax
;
170 if (xmin
==0 && xmax
==MAXX
) /* clear section of screen as needed */
172 if (ymin
==0) cl_up(79,ymax
);
173 else for (i
=ymin
; i
<ymin
; i
++) cl_line(1,i
+1);
176 d_xmin
=xmin
; d_xmax
=xmax
; d_ymin
=ymin
; d_ymax
=ymax
; /* for limited screen drawing */
178 if (xmin
<=0 && xmax
==MAXX
) /* draw stuff on right side of screen as needed*/
180 for (i
=ymin
; i
<ymax
; i
++)
182 idx
= bot_data
[i
].typ
;
185 cursor(70,i
+1); lprcat(bot_data
[i
].string
);
195 subroutine to redraw the whole screen as the player knows it
197 char screen
[MAXX
][MAXY
],d_flag
; /* template for the screen */
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
)
204 d_flag
=1; clear(); /* clear the screen */
208 d_flag
=0; cursor(1,1);
211 d_xmin
=0; /* d_xmin=-1 means display all without bottomline */
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
] = ' ';
220 for (i
=d_ymin
; i
<d_ymax
; i
++)
222 j
=d_xmin
; while ((screen
[j
][i
]==' ') && (j
<d_xmax
)) j
++;
224 if (j
>= d_xmax
) m
=d_xmin
; /* don't search backwards if blank line */
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;
234 for (k
=j
; k
<=j
+3; k
++) if (screen
[k
][i
] != ' ') k
=1000;
236 { while(screen
[j
][i
]==' ' && j
<=m
) j
++; cursor(j
+1,i
+1); }
238 lprc(screen
[j
++][i
]);
241 setbold(); /* print out only bold objects now */
243 for (lastx
=lasty
=127, i
=d_ymin
; i
<d_ymax
; i
++)
244 for (j
=d_xmin
; j
<d_xmax
; j
++)
248 if ((know
[j
][i
]) && (mitem
[j
][i
]==0))
249 if (objnamelist
[k
]!=' ')
251 if (lasty
!=i
+1 || lastx
!=j
)
252 cursor(lastx
=j
+1,lasty
=i
+1); else lastx
++;
253 lprc(objnamelist
[k
]);
257 resetbold(); if (d_flag
) { always
=1; botside(); always
=1; bot_linex(); }
259 d_xmin
= 0 , d_xmax
= MAXX
, d_ymin
= 0 , d_ymax
= MAXY
; /* for limited screen drawing */
265 subroutine to display a cell location on the screen
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; }
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;
278 for (j
=miny
; j
<=maxy
; j
++)
279 for (m
=minx
; m
<=maxx
; m
++)
283 x
=maxx
; while (know
[x
][j
]) --x
;
286 if ((k
=mitem
[i
][j
]) != 0) lprc(monstnamelist
[k
]);
287 else switch(k
=item
[i
][j
])
289 case OWALL
: case 0: case OIVTELETRAP
: case OTRAPARROWIV
:
290 case OIVDARTRAP
: case OIVTRAPDOOR
:
291 lprc(objnamelist
[k
]); break;
293 default: setbold(); lprc(objnamelist
[k
]); resetbold();
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
309 if (c
[BLINDCOUNT
]) return; /* see nothing if blind */
311 if ((k
=mitem
[x
][y
]) != 0) lprc(monstnamelist
[k
]);
312 else switch(k
=item
[x
][y
])
314 case OWALL
: case 0: case OIVTELETRAP
: case OTRAPARROWIV
:
315 case OIVDARTRAP
: case OIVTRAPDOOR
:
316 lprc(objnamelist
[k
]); break;
318 default: setbold(); lprc(objnamelist
[k
]); resetbold();
320 know
[x
][y
]|=1; /* we end up knowing about it */
326 subroutine to show where the player is on the screen
327 cursor values start from 1 up
331 cursor(playerx
+1,playery
+1);
332 oldx
=playerx
; oldy
=playery
;
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
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
344 short diroffx
[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
345 short diroffy
[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
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 */
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)
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); }
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);
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
374 static int lincount
,count
;
378 register int i
,number
;
379 count
= lincount
= 0; nosignal
=1;
381 if (arg
== -1) /* if display spells while casting one */
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);
389 resetscroll(); clear();
392 lprcat("The magic spells you have discovered thus far:\n\n");
393 for (i
=0; i
<SPNUM
; i
++)
395 { lprintf("%s %-20s ",spelcode
[i
],spelname
[i
]); seepage(); }
399 seepage(); more(); nosignal
=0;
400 draws(0,MAXX
,0,number
); return;
403 lincount
+= 3; if (count
!=0) { count
=2; seepage(); }
405 lprcat("\nThe magic scrolls you have found to date are:\n\n");
407 for (i
=0; i
<MAXSCROLL
; i
++)
408 if (scrollname
[i
][0])
409 if (scrollname
[i
][1]!=' ')
410 { lprintf("%-26s",&scrollname
[i
][1]); seepage(); }
412 lincount
+= 3; if (count
!=0) { count
=2; seepage(); }
414 lprcat("\nThe magic potions you have found to date are:\n\n");
416 for (i
=0; i
<MAXPOTION
; i
++)
417 if (potionname
[i
][0])
418 if (potionname
[i
][1]!=' ')
419 { lprintf("%-26s",&potionname
[i
][1]); seepage(); }
421 if (lincount
!=0) more(); nosignal
=0; setscroll(); drawscreen();
425 * subroutine to paginate the seemagic function
431 lincount
++; count
=0; lprc('\n');
432 if (lincount
>17) { lincount
=0; more(); clear(); }