comparison xrogue/io.c @ 142:6b5fbd7c3ece

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