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 void bot_hpx(void);
7 static void bot_spellx(void);
8 static void botside(void);
9 static void botsub(int, const char *);
10 static void seepage(void);
12 static int minx
, maxx
, miny
, maxy
, k
, m
;
13 static char bot1f
= 0, bot2f
= 0, bot3f
= 0;
18 now for the bottom line of the display
43 bot3f
= bot1f
= bot2f
= 0;
61 if (cbak
[SPELLS
] <= -50 || (always
)) {
64 lprintf("Spells:%3d(%3d)", (long)c
[SPELLS
], (long)c
[SPELLMAX
]);
66 lprintf("Spells:%3d(%2d) ", (long)c
[SPELLS
], (long)c
[SPELLMAX
]);
67 lprintf(" AC: %-3d WC: %-3d Level", (long)c
[AC
], (long)c
[WCLASS
]);
69 lprintf("%3d", (long)c
[LEVEL
]);
71 lprintf(" %-2d", (long)c
[LEVEL
]);
72 lprintf(" Exp: %-9d %s\n", (long)c
[EXPERIENCE
], class[c
[LEVEL
] - 1]);
73 lprintf("HP: %3d(%3d) STR=%-2d INT=%-2d ",
74 (long)c
[HP
], (long)c
[HPMAX
], (long)(c
[STRENGTH
] + c
[STREXTRA
]), (long)c
[INTELLIGENCE
]);
75 lprintf("WIS=%-2d CON=%-2d DEX=%-2d CHA=%-2d LV:",
76 (long)c
[WISDOM
], (long)c
[CONSTITUTION
], (long)c
[DEXTERITY
], (long)c
[CHARISMA
]);
78 if ((level
== 0) || (wizard
))
83 lprcat(levelname
[(int)level
]);
84 lprintf(" Gold: %-6d", (long)c
[GOLD
]);
87 c
[TMP
] = c
[STRENGTH
] + c
[STREXTRA
];
88 for (i
= 0; i
< 100; i
++)
92 botsub(makecode(SPELLS
, 8, 18), "%3d");
94 botsub(makecode(SPELLMAX
, 12, 18), "%3d)");
96 botsub(makecode(SPELLMAX
, 12, 18), "%2d) ");
97 botsub(makecode(HP
, 5, 19), "%3d");
98 botsub(makecode(HPMAX
, 9, 19), "%3d");
99 botsub(makecode(AC
, 21, 18), "%-3d");
100 botsub(makecode(WCLASS
, 30, 18), "%-3d");
101 botsub(makecode(EXPERIENCE
, 49, 18), "%-9d");
102 if (c
[LEVEL
] != cbak
[LEVEL
]) {
104 lprcat(class[c
[LEVEL
] - 1]);
107 botsub(makecode(LEVEL
, 40, 18), "%3d");
109 botsub(makecode(LEVEL
, 40, 18), " %-2d");
110 c
[TMP
] = c
[STRENGTH
] + c
[STREXTRA
];
111 botsub(makecode(TMP
, 18, 19), "%-2d");
112 botsub(makecode(INTELLIGENCE
, 25, 19), "%-2d");
113 botsub(makecode(WISDOM
, 32, 19), "%-2d");
114 botsub(makecode(CONSTITUTION
, 39, 19), "%-2d");
115 botsub(makecode(DEXTERITY
, 46, 19), "%-2d");
116 botsub(makecode(CHARISMA
, 53, 19), "%-2d");
117 if ((level
!= cbak
[CAVELEVEL
]) || (c
[TELEFLAG
] != cbak
[TELEFLAG
])) {
118 if ((level
== 0) || (wizard
))
120 cbak
[TELEFLAG
] = c
[TELEFLAG
];
121 cbak
[CAVELEVEL
] = level
;
126 lprcat(levelname
[(int)level
]);
128 botsub(makecode(GOLD
, 69, 19), "%-6d");
133 special subroutine to update only the gold number on the bottomlines
139 botsub(makecode(GOLD
, 69, 19), "%-6d");
143 special routine to update hp and level fields on bottom lines
144 called in monster.c hitplayer() and spattack()
149 if (c
[EXPERIENCE
] != cbak
[EXPERIENCE
]) {
153 botsub(makecode(HP
, 5, 19), "%3d");
157 special routine to update number of spells called from regen()
162 botsub(makecode(SPELLS
, 9, 18), "%2d");
166 common subroutine for a more economical bottomline()
168 static struct bot_side_def
{
173 { STEALTH
, "stealth" },
174 { UNDEADPRO
, "undead pro" },
175 { SPIRITPRO
, "spirit pro" },
176 { CHARMCOUNT
, "Charm" },
177 { TIMESTOP
, "Time Stop" },
178 { HOLDMONST
, "Hold Monst" },
179 { GIANTSTR
, "Giant Str" },
180 { FIRERESISTANCE
, "Fire Resit" },
181 { DEXCOUNT
, "Dexterity" },
182 { STRCOUNT
, "Strength" },
183 { SCAREMONST
, "Scare" },
184 { HASTESELF
, "Haste Self" },
185 { CANCELLATION
, "Cancel" },
186 { INVISIBILITY
, "Invisible" },
187 { ALTPRO
, "Protect 3" },
188 { PROTECTIONTIME
, "Protect 2" },
196 for (i
= 0; i
< 17; i
++) {
197 idx
= bot_data
[i
].typ
;
198 if ((always
) || (c
[idx
] != cbak
[idx
])) {
199 if ((always
) || (cbak
[idx
] == 0)) {
202 lprcat(bot_data
[i
].string
);
204 } else if (c
[idx
] == 0) {
215 botsub(int idx
, const char *str
)
219 x
= (idx
>> 8) & 0xff;
221 if (c
[idx
] != cbak
[idx
]) {
224 lprintf(str
, (long)c
[idx
]);
229 * subroutine to draw only a section of the screen
230 * only the top section of the screen is updated.
231 * If entire lines are being drawn, then they will be cleared first.
233 /* for limited screen drawing */
234 int d_xmin
= 0, d_xmax
= MAXX
, d_ymin
= 0, d_ymax
= MAXY
;
237 draws(int xmin
, int xmax
, int ymin
, int ymax
)
240 /* clear section of screen as needed */
241 if (xmin
== 0 && xmax
== MAXX
) {
245 for (i
= ymin
; i
< ymin
; i
++)
249 d_xmin
= xmin
; /* for limited screen drawing */
254 /* draw stuff on right side of screen as needed */
255 if (xmin
<= 0 && xmax
== MAXX
) {
256 for (i
= ymin
; i
< ymax
; i
++) {
257 idx
= bot_data
[i
].typ
;
260 lprcat(bot_data
[i
].string
);
270 subroutine to redraw the whole screen as the player knows it
272 char screen
[MAXX
][MAXY
], d_flag
; /* template for the screen */
278 int lastx
, lasty
; /* variables used to optimize the object printing */
279 if (d_xmin
== 0 && d_xmax
== MAXX
&& d_ymin
== 0 && d_ymax
== MAXY
) {
281 clear(); /* clear the screen */
286 /* d_xmin=-1 means display all without bottomline */
290 for (i
= d_ymin
; i
< d_ymax
; i
++)
291 for (j
= d_xmin
; j
< d_xmax
; j
++)
294 else if ((l
= mitem
[j
][i
]) != 0)
295 screen
[j
][i
] = monstnamelist
[l
];
296 else if ((l
= item
[j
][i
]) == OWALL
)
301 for (i
= d_ymin
; i
< d_ymax
; i
++) {
303 while ((j
< d_xmax
) && (screen
[j
][i
] == ' '))
306 if (j
>= d_xmax
) /* don't search backwards if blank line */
308 else { /* search backwards for end of line */
310 while ((screen
[m
][i
] == ' ') && (m
> d_xmin
))
313 cursor(j
+ 1, i
+ 1);
319 for (l
= j
; l
<= j
+ 3; l
++)
320 if (screen
[l
][i
] != ' ')
323 while (j
<= m
&& screen
[j
][i
] == ' ')
325 cursor(j
+ 1, i
+ 1);
328 lprc(screen
[j
++][i
]);
331 setbold(); /* print out only bold objects now */
333 for (lastx
= lasty
= 127, i
= d_ymin
; i
< d_ymax
; i
++)
334 for (j
= d_xmin
; j
< d_xmax
; j
++) {
335 if ((l
= item
[j
][i
]) != 0)
337 if ((know
[j
][i
]) && (mitem
[j
][i
] == 0))
338 if (objnamelist
[l
] != ' ') {
339 if (lasty
!= i
+ 1 || lastx
!= j
)
340 cursor(lastx
= j
+ 1, lasty
= i
+ 1);
343 lprc(objnamelist
[l
]);
356 d_xmin
= 0, d_xmax
= MAXX
, d_ymin
= 0, d_ymax
= MAXY
; /* for limited screen drawing */
362 subroutine to display a cell location on the screen
365 showcell(int x
, int y
)
368 if (c
[BLINDCOUNT
]) /* see nothing if blind */
391 for (j
= miny
; j
<= maxy
; j
++)
392 for (n
= minx
; n
<= maxx
; n
++)
393 if (know
[n
][j
] == 0) {
394 cursor(n
+ 1, j
+ 1);
398 for (i
= n
; i
<= x
; i
++) {
399 if ((l
= mitem
[i
][j
]) != 0)
400 lprc(monstnamelist
[l
]);
402 switch (l
= item
[i
][j
]) {
409 lprc(objnamelist
[l
]);
414 lprc(objnamelist
[l
]);
424 this routine shows only the spot that is given it. the spaces around
425 these coordinated are not shown
426 used in godirect() in monster.c for missile weapons display
429 show1cell(int x
, int y
)
431 if (c
[BLINDCOUNT
]) /* see nothing if blind */
433 cursor(x
+ 1, y
+ 1);
434 if ((k
= mitem
[x
][y
]) != 0)
435 lprc(monstnamelist
[k
]);
437 switch (k
= item
[x
][y
]) {
444 lprc(objnamelist
[k
]);
449 lprc(objnamelist
[k
]);
452 know
[x
][y
] |= 1; /* we end up knowing about it */
458 subroutine to show where the player is on the screen
459 cursor values start from 1 up
464 cursor(playerx
+ 1, playery
+ 1);
472 subroutine to move the player from one room to another
473 returns 0 if can't move in that direction or hit a monster or on an object
475 nomove is set to 1 to stop the next move (inadvertent monsters hitting
476 players when walking into walls) if player walks off screen or into wall
478 short diroffx
[] = { 0, 0, 1, 0, -1, 1, -1, 1, -1 };
479 short diroffy
[] = { 0, 1, 0, -1, 0, -1, -1, 1, 1 };
482 * from = present room # direction = [1-north]
483 * [2-east] [3-south] [4-west] [5-northeast]
484 * [6-northwest] [7-southeast] [8-southwest]
485 * if direction=0, don't move--just show where he is
491 if (c
[CONFUSE
]) /*if confused any dir */
492 if (c
[LEVEL
] < rnd(30))
494 l
= playerx
+ diroffx
[dir
];
495 n
= playery
+ diroffy
[dir
];
496 if (l
< 0 || l
>= MAXX
|| n
< 0 || n
>= MAXY
) {
498 return (yrepcount
= 0);
503 if (i
== OWALL
&& c
[WTW
] == 0) {
505 return (yrepcount
= 0);
507 if (l
== 33 && n
== MAXY
- 1 && level
== 1) {
509 for (l
= 0; l
< MAXX
; l
++)
510 for (n
= 0; n
< MAXY
; n
++)
511 if (item
[l
][n
] == OENTRANCE
) {
522 return (yrepcount
= 0);
528 if (i
&& i
!= OTRAPARROWIV
&& i
!= OIVTELETRAP
&& i
!= OIVDARTRAP
&& i
!= OIVTRAPDOOR
)
529 return (yrepcount
= 0);
535 * function to show what magic items have been discovered thus far
536 * enter with -1 for just spells, anything else will give scrolls & potions
538 static int lincount
, count
;
544 count
= lincount
= 0;
547 if (arg
== -1) { /* if display spells while casting one */
548 for (number
= i
= 0; i
< SPNUM
; i
++)
551 number
= (number
+ 2) / 3 + 4; /* # lines needed to display */
559 lprcat("The magic spells you have discovered thus far:\n\n");
560 for (i
= 0; i
< SPNUM
; i
++)
562 lprintf("%s %-20s ", spelcode
[i
], spelname
[i
]);
570 draws(0, MAXX
, 0, number
);
580 lprcat("\nThe magic scrolls you have found to date are:\n\n");
582 for (i
= 0; i
< MAXSCROLL
; i
++)
583 if (scrollname
[i
][0])
584 if (scrollname
[i
][1] != ' ') {
585 lprintf("%-26s", &scrollname
[i
][1]);
595 lprcat("\nThe magic potions you have found to date are:\n\n");
597 for (i
= 0; i
< MAXPOTION
; i
++)
598 if (potionname
[i
][0])
599 if (potionname
[i
][1] != ' ') {
600 lprintf("%-26s", &potionname
[i
][1]);
612 * subroutine to paginate the seemagic function