2 * Copyright (c) 1983-2003, Regents of the University of California.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. Neither the name of the University of California, San Francisco nor
15 * the names of its contributors may be used to endorse or promote
16 * products derived from this software without specific prior written
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
20 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 * $OpenBSD: draw.c,v 1.7 2003/06/11 08:45:33 pjanzen Exp $
32 * $NetBSD: draw.c,v 1.2 1997/10/10 16:33:04 lukem Exp $
33 * $DragonFly: src/games/hunt/huntd/draw.c,v 1.2 2008/09/04 16:12:51 swildner Exp $
42 static char translate(char);
43 static int player_sym(PLAYER
*, int, int);
44 static void drawstatus(PLAYER
*);
45 static void see(PLAYER
*, int);
49 * Draw the entire maze on a player's screen.
59 /* Clear the client's screen: */
61 /* Draw the top row of the maze: */
62 outstr(pp
, pp
->p_maze
[0], WIDTH
);
63 for (y
= 1; y
< HEIGHT
- 1; y
++) {
64 endp
= &pp
->p_maze
[y
][WIDTH
];
65 for (x
= 0, sp
= pp
->p_maze
[y
]; sp
< endp
; x
++, sp
++)
68 /* Draw the player as themselves */
69 if (pp
->p_x
== x
&& pp
->p_y
== y
)
70 outch(pp
, translate(*sp
));
71 /* Possibly draw other players as team nrs */
72 else if (is_player(*sp
))
73 outch(pp
, player_sym(pp
, y
, x
));
78 /* Draw the last row of the maze: */
79 cgoto(pp
, HEIGHT
- 1, 0);
80 outstr(pp
, pp
->p_maze
[HEIGHT
- 1], WIDTH
);
85 * drawstatus - put up the status lines (this assumes the screen
86 * size is 80x24 with the maze being 64x24)
89 drawstatus(PLAYER
*pp
)
94 outyx(pp
, STAT_AMMO_ROW
, STAT_LABEL_COL
, "Ammo:");
97 outyx(pp
, STAT_GUN_ROW
, STAT_LABEL_COL
, "Gun:");
98 outyx(pp
, STAT_GUN_ROW
, STAT_VALUE_COL
, "%3s",
99 (pp
->p_ncshot
< conf_maxncshot
) ? "ok" : "");
101 outyx(pp
, STAT_DAM_ROW
, STAT_LABEL_COL
, "Damage:");
102 outyx(pp
, STAT_DAM_ROW
, STAT_VALUE_COL
, "%2d/%2d",
103 pp
->p_damage
, pp
->p_damcap
);
105 outyx(pp
, STAT_KILL_ROW
, STAT_LABEL_COL
, "Kills:");
106 outyx(pp
, STAT_KILL_ROW
, STAT_VALUE_COL
, "%3d",
107 (pp
->p_damcap
- conf_maxdam
) / 2);
109 outyx(pp
, STAT_PLAY_ROW
, STAT_LABEL_COL
, "Player:");
110 for (i
= STAT_PLAY_ROW
+ 1, np
= Player
; np
< End_player
; np
++, i
++) {
111 outyx(pp
, i
, STAT_NAME_COL
, "%5.2f%c%-10.10s %c",
112 np
->p_ident
->i_score
, stat_char(np
),
113 np
->p_ident
->i_name
, np
->p_ident
->i_team
);
116 outyx(pp
, STAT_MON_ROW
, STAT_LABEL_COL
, "Monitor:");
117 for (i
= STAT_MON_ROW
+ 1, np
= Monitor
; np
< End_monitor
; np
++, i
++) {
118 outyx(pp
, i
++, STAT_NAME_COL
, "%5.5s %-10.10s %c",
119 " ", np
->p_ident
->i_name
, np
->p_ident
->i_team
);
125 * check and update the visible area around the player
136 * The player is aware of all objects immediately adjacent to
139 check(pp
, y
- 1, x
- 1);
140 check(pp
, y
- 1, x
);
141 check(pp
, y
- 1, x
+ 1);
142 check(pp
, y
, x
- 1);
144 check(pp
, y
, x
+ 1);
145 check(pp
, y
+ 1, x
- 1);
146 check(pp
, y
+ 1, x
);
147 check(pp
, y
+ 1, x
+ 1);
149 switch (pp
->p_face
) {
150 /* The player can see down corridors in directions except behind: */
171 /* But they don't see too far when they are flying about: */
176 /* Move the cursor back over the player: */
182 * Look down a corridor, or towards an open space. This
183 * is a simulation of visibility from the player's perspective.
186 see(PLAYER
*pp
, int face
)
191 /* Start from the player's position: */
195 #define seewalk(dx, dy) \
199 while (See_over[(int)*sp]) { \
202 sp += ((dx) + (dy) * sizeof Maze[0]); \
203 check(pp, y + dx, x + dy); \
205 check(pp, y - dx, x - dy); \
210 seewalk(-1, 0); break;
212 seewalk(1, 0); break;
214 seewalk(0, -1); break;
216 seewalk(0, 1); break;
222 * The player is aware of a cell in the maze.
223 * Ensure it is shown properly on their screen.
226 check(PLAYER
*pp
, int y
, int x
)
232 if (pp
== ALL_PLAYERS
) {
233 for (pp
= Player
; pp
< End_player
; pp
++)
235 for (pp
= Monitor
; pp
< End_monitor
; pp
++)
240 i
= y
* sizeof Maze
[0] + x
;
241 ch
= ((char *) Maze
)[i
];
242 if (ch
!= ((char *) pp
->p_maze
)[i
]) {
245 if (x
== rpp
->p_x
&& y
== rpp
->p_y
)
246 outch(rpp
, translate(ch
));
247 else if (is_player(ch
))
248 outch(rpp
, player_sym(rpp
, y
, x
));
251 ((char *) rpp
->p_maze
)[i
] = ch
;
257 * Update the status of a player on everyone's screen
264 STAT_PLAY_ROW
+ 1 + (pp
- Player
), STAT_SCAN_COL
,
265 "%c", stat_char(pp
));
270 * Draw the player on the screen and show him to everyone who's scanning
271 * unless he is cloaked.
272 * The 'draw' flag when false, causes the 'saved under' character to
273 * be drawn instead of the player; effectively un-drawing the player.
276 drawplayer(PLAYER
*pp
, FLAG draw
)
284 /* Draw or un-draw the player into the master map: */
285 Maze
[y
][x
] = draw
? pp
->p_face
: pp
->p_over
;
287 /* The monitors can always see this player: */
288 for (newp
= Monitor
; newp
< End_monitor
; newp
++)
291 /* Check if other players can see this player: */
292 for (newp
= Player
; newp
< End_player
; newp
++) {
294 /* When un-drawing, show everyone what was under */
299 /* The player can always see themselves: */
303 /* Check if the other player just run out of scans */
304 if (newp
->p_scan
== 0) {
305 /* The other player is no longer scanning: */
308 /* Check if the other play is scannning */
309 } else if (newp
->p_scan
> 0) {
310 /* If this player's not cloacked, draw him: */
313 /* And this uses up a scan. */
318 /* Use up one point of cloak time when drawing: */
319 if (draw
&& pp
->p_cloak
>= 0) {
321 /* Check if we ran out of cloak: */
329 * Write a message at the bottom of the screen.
332 message(PLAYER
*pp
, const char *s
)
334 cgoto(pp
, HEIGHT
, 0);
335 outstr(pp
, s
, strlen(s
));
341 * Turn a player character into a more personal player character.
342 * ie: {,},!,i becomes <,>,v,^
362 * Return the symbol for the player at (y,x) when viewed by player 'pp'.
363 * ie: - unteamed players appear as {,},!,i
364 * - unteamed monitors see all players as team digits
365 * - teamed players see other players on their team, as a digit
368 player_sym(PLAYER
*pp
, int y
, int x
)
373 if (npp
->p_ident
->i_team
== ' ')
375 if (pp
->p_ident
->i_team
== '*')
376 return npp
->p_ident
->i_team
;
377 if (pp
->p_ident
->i_team
!= npp
->p_ident
->i_team
)
379 return pp
->p_ident
->i_team
;