comparison xrogue/io.c @ 133:e6179860cb76

Import XRogue 8.0 from the Roguelike Restoration Project (r1490)
author John "Elwin" Edwards
date Tue, 21 Apr 2015 08:55:20 -0400
parents
children ce0cf824c192
comparison
equal deleted inserted replaced
124:d10fc4a065ac 133:e6179860cb76
1 /*
2 io.c - Various input/output functions
3
4 XRogue: Expeditions into the Dungeons of Doom
5 Copyright (C) 1991 Robert Pietkivitch
6 All rights reserved.
7
8 Based on "Advanced Rogue"
9 Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
10 All rights reserved.
11
12 Based on "Rogue: Exploring the Dungeons of Doom"
13 Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
14 All rights reserved.
15
16 See the file LICENSE.TXT for full copyright and licensing information.
17 */
18
19 #include <curses.h>
20 #include <ctype.h>
21 #include <stdarg.h>
22 #include "rogue.h"
23
24 /*
25 * msg:
26 * Display a message at the top of the screen.
27 */
28
29 static char msgbuf[BUFSIZ];
30 static int newpos = 0;
31
32 /* VARARGS */
33 void
34 msg(char *fmt, ...)
35 {
36 va_list ap;
37 /*
38 * if the string is "", just clear the line
39 */
40 if (*fmt == '\0')
41 {
42 wclear(msgw);
43 overwrite(cw, msgw);
44 wmove(msgw, 0, 0);
45 clearok(msgw, FALSE);
46 draw(msgw);
47 mpos = 0;
48 return;
49 }
50 /*
51 * otherwise add to the message and flush it out
52 */
53 va_start(ap, fmt);
54 doadd(fmt, ap);
55 va_end(ap);
56 endmsg();
57 }
58
59 /*
60 * add things to the current message
61 */
62
63 /* VARARGS */
64 void
65 addmsg(char *fmt, ...)
66 {
67 va_list ap;
68
69 va_start(ap, fmt);
70 doadd(fmt, ap);
71 va_end(ap);
72 }
73
74 /*
75 * If there is no current message, do nothing. Otherwise, prompt the
76 * player with the --More-- string. Then erase the message.
77 */
78
79 rmmsg()
80 {
81 if (mpos) {
82 wclear(msgw);
83 overwrite(cw, msgw);
84 mvwaddstr(msgw, 0, 0, huh);
85 waddstr(msgw, morestr);
86 clearok(msgw, FALSE);
87 draw(msgw);
88 wait_for(' ');
89 msg("");
90 }
91 }
92
93 /*
94 * Display a new msg (giving him a chance to see the previous one if it
95 * is up there with the --More--)
96 */
97
98 endmsg()
99 {
100 /* Needed to track where we are for 5.0 (PC) curses */
101 register int x, y;
102
103 if (mpos) {
104 /*
105 * If this message will fit on the line (plus space for --More--)
106 * then just add it (only during combat).
107 */
108 if (player.t_quiet < 0 && mpos + newpos + strlen(morestr) + 5 < cols) {
109 wmove(msgw, 0, mpos + 5);
110 newpos += mpos + 5;
111 strcat(huh, " ");
112 }
113 else {
114 wclear(msgw);
115 overwrite(cw, msgw);
116 mvwaddstr(msgw, 0, 0, huh);
117 waddstr(msgw, morestr);
118 clearok(msgw, FALSE);
119 draw(msgw);
120 wait_for(' ');
121 wclear(msgw);
122 overwrite(cw, msgw);
123 wmove(msgw, 0, 0);
124 huh[0] = '\0';
125 }
126 }
127 else {
128 wclear(msgw);
129 overwrite(cw, msgw);
130 wmove(msgw, 0, 0);
131 huh[0] = '\0';
132 }
133 strcat(huh, msgbuf);
134 mvwaddstr(msgw, 0, 0, huh);
135 getyx(msgw, y, x);
136 mpos = newpos;
137 newpos = 0;
138 wmove(msgw, y, x);
139 clearok(msgw, FALSE);
140 draw(msgw);
141 }
142
143 doadd(char *fmt, va_list ap)
144 {
145 vsprintf((char *) &msgbuf[newpos], fmt, ap);
146 newpos = strlen(msgbuf);
147 }
148
149 /*
150 * step_ok:
151 * returns true if it is ok for type to step on ch
152 * flgptr will be NULL if we don't know what the monster is yet!
153 */
154
155 step_ok(y, x, can_on_monst, flgptr)
156 register int y, x, can_on_monst;
157 register struct thing *flgptr;
158 {
159 /* can_on_monst = MONSTOK if all we care about are physical obstacles */
160 register struct linked_list *item;
161 register struct thing *tp;
162 unsigned char ch;
163
164 /* What is here? Don't check monster window if MONSTOK is set */
165 if (can_on_monst == MONSTOK) ch = mvinch(y, x);
166 else ch = winat(y, x);
167
168 if (can_on_monst == FIGHTOK && isalpha(ch) &&
169 (item = find_mons(y, x)) != NULL) {
170 tp = THINGPTR(item); /* What monster is here? */
171
172 /* We can hit it if we're after it */
173 if (flgptr->t_dest == &tp->t_pos) return TRUE;
174
175 /*
176 * Otherwise, if we're friendly we'll hit it unless it is also
177 * friendly or is our race.
178 */
179 if (off(*flgptr, ISFRIENDLY) ||
180 on(*tp, ISFRIENDLY) ||
181 flgptr->t_index == tp->t_index) return FALSE;
182 else return TRUE;
183 }
184 else switch (ch)
185 {
186 case ' ':
187 case VERTWALL:
188 case HORZWALL:
189 case SECRETDOOR:
190 if (flgptr && on(*flgptr, CANINWALL)) return(TRUE);
191 return FALSE;
192 when SCROLL:
193 if (can_on_monst == MONSTOK) { /* Not a real obstacle */
194 move_free = 0; /* check free movement */
195 return(TRUE);
196 }
197 /*
198 * If it is a scroll, it might be a scare monster scroll
199 * so we need to look it up to see what type it is.
200 */
201 if (flgptr && flgptr->t_ctype == C_MONSTER) {
202 move_free = 1;
203 item = find_obj(y, x);
204 if (item != NULL &&
205 (OBJPTR(item))->o_which==S_SCARE &&
206 (flgptr == NULL || flgptr->t_stats.s_intel < 17)) {
207 move_free = 2;
208 return(FALSE); /* All but smart ones are scared */
209 }
210 }
211 return(TRUE);
212 otherwise:
213 return (!isalpha(ch));
214 }
215 /* return(FALSE); */
216 /*NOTREACHED*/
217 }
218
219 /*
220 * shoot_ok:
221 * returns true if it is ok for type to shoot over ch
222 */
223
224 shoot_ok(int ch)
225 {
226 switch (ch)
227 {
228 case ' ':
229 case VERTWALL:
230 case HORZWALL:
231 case SECRETDOOR:
232 case FOREST:
233 return FALSE;
234 default:
235 return (!isalpha(ch));
236 }
237 }
238
239 /*
240 * status:
241 * Display the important stats line. Keep the cursor where it was.
242 */
243
244 status(display)
245 bool display; /* is TRUE, display unconditionally */
246 {
247 register struct stats *stat_ptr, *max_ptr;
248 register int oy = 0, ox = 0, temp;
249 register char *pb;
250 char buf[LINELEN];
251 static int hpwidth = 0, s_hungry = -1;
252 static int s_lvl = -1, s_hp = -1, s_str, maxs_str,
253 s_ac = 0;
254 static short s_intel, s_dext, s_wisdom, s_const, s_charisma;
255 static short maxs_intel, maxs_dext, maxs_wisdom, maxs_const, maxs_charisma;
256 static unsigned long s_exp = 0;
257 static int s_carry, s_pack;
258 bool first_line=FALSE;
259
260 /* Go to English mode */
261 nofont(cw);
262
263 stat_ptr = &pstats;
264 max_ptr = &max_stats;
265
266 /*
267 * If nothing has changed in the first line, then skip it
268 */
269 if (!display &&
270 s_lvl == level &&
271 s_intel == stat_ptr->s_intel &&
272 s_wisdom == stat_ptr->s_wisdom &&
273 s_dext == dex_compute() &&
274 s_const == stat_ptr->s_const &&
275 s_charisma == stat_ptr->s_charisma &&
276 s_str == str_compute() &&
277 s_hungry == hungry_state &&
278 maxs_intel == max_ptr->s_intel &&
279 maxs_wisdom == max_ptr->s_wisdom &&
280 maxs_dext == max_ptr->s_dext &&
281 maxs_const == max_ptr->s_const &&
282 maxs_charisma == max_ptr->s_charisma &&
283 maxs_str == max_ptr->s_str ) goto line_two;
284
285 /* Display the first line */
286 first_line = TRUE;
287 getyx(cw, oy, ox);
288 sprintf(buf, "Int:%d(%d) Str:%d", stat_ptr->s_intel,
289 max_ptr->s_intel, str_compute());
290
291 /* Maximum strength */
292 pb = &buf[strlen(buf)];
293 sprintf(pb, "(%d)", max_ptr->s_str);
294
295 pb = &buf[strlen(buf)];
296 sprintf(pb, " Wis:%d(%d) Dxt:%d(%d) Con:%d(%d) Cha:%d(%d)",
297 stat_ptr->s_wisdom,max_ptr->s_wisdom,dex_compute(),max_ptr->s_dext,
298 stat_ptr->s_const,max_ptr->s_const,stat_ptr->s_charisma,
299 max_ptr->s_charisma);
300
301 /* Update first line status */
302 s_intel = stat_ptr->s_intel;
303 s_wisdom = stat_ptr->s_wisdom;
304 s_dext = dex_compute();
305 s_const = stat_ptr->s_const;
306 s_charisma = stat_ptr->s_charisma;
307 s_str = str_compute();
308 maxs_intel = max_ptr->s_intel;
309 maxs_wisdom = max_ptr->s_wisdom;
310 maxs_dext = max_ptr->s_dext;
311 maxs_const = max_ptr->s_const;
312 maxs_charisma = max_ptr->s_charisma;
313 maxs_str = max_ptr->s_str;
314
315 /* Print the line */
316 mvwaddstr(cw, lines-2, 0, buf);
317 switch (hungry_state) {
318 case F_SATIATED:
319 waddstr(cw, " Satiated");
320 when F_OKAY: ;
321 when F_HUNGRY:
322 waddstr(cw, " Hungry");
323 when F_WEAK:
324 waddstr(cw, " Weak");
325 when F_FAINT:
326 waddstr(cw, " Fainting");
327 }
328 wclrtoeol(cw);
329 s_hungry = hungry_state;
330
331 /*
332 * If nothing has changed since the last status, don't
333 * bother.
334 */
335 line_two:
336 if (!display &&
337 s_lvl == level &&
338 s_hp == stat_ptr->s_hpt &&
339 s_ac == ac_compute(FALSE) - dext_prot(s_dext) &&
340 s_pack == stat_ptr->s_pack &&
341 s_carry == stat_ptr->s_carry &&
342 s_exp == stat_ptr->s_exp ) {
343 newfont(cw);
344 return;
345 }
346
347 if (!first_line) getyx(cw, oy, ox);
348 if (s_hp != max_ptr->s_hpt) {
349 temp = s_hp = max_ptr->s_hpt;
350 for (hpwidth = 0; temp; hpwidth++)
351 temp /= 10;
352 }
353 sprintf(buf, "Lvl:%d Hp:%*d(%*d) Ac:%d Carry:%d(%d) Exp:%d/%lu %s",
354 level, hpwidth, stat_ptr->s_hpt, hpwidth, max_ptr->s_hpt,
355 ac_compute(FALSE) - dext_prot(s_dext),stat_ptr->s_pack/10,
356 stat_ptr->s_carry/10, stat_ptr->s_lvl, stat_ptr->s_exp,
357 cnames[player.t_ctype][min(stat_ptr->s_lvl-1, NUM_CNAMES-1)]);
358
359 /*
360 * Save old status
361 */
362 s_lvl = level;
363 s_hp = stat_ptr->s_hpt;
364 s_ac = ac_compute(FALSE) - dext_prot(s_dext);
365 s_pack = stat_ptr->s_pack;
366 s_carry = stat_ptr->s_carry;
367 s_exp = stat_ptr->s_exp;
368 mvwaddstr(cw, lines-1, 0, buf);
369 wclrtoeol(cw);