Mercurial > hg > early-roguelike
comparison arogue5/move.c @ 63:0ed67132cf10
Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 09 Aug 2012 22:58:48 +0000 |
parents | |
children | a0a57cf42810 |
comparison
equal
deleted
inserted
replaced
62:0ef99244acb8 | 63:0ed67132cf10 |
---|---|
1 /* | |
2 * Hero movement commands | |
3 * | |
4 * Advanced Rogue | |
5 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T | |
6 * All rights reserved. | |
7 * | |
8 * Based on "Super-Rogue" | |
9 * Copyright (C) 1984 Robert D. Kindelberger | |
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 "rogue.h" | |
22 | |
23 /* | |
24 * Used to hold the new hero position | |
25 */ | |
26 | |
27 static coord nh; | |
28 | |
29 static const char Moves[3][3] = { | |
30 { 'y', 'k', 'u' }, | |
31 { 'h', '\0', 'l' }, | |
32 { 'b', 'j', 'n' } | |
33 }; | |
34 | |
35 /* | |
36 * be_trapped: | |
37 * The guy stepped on a trap.... Make him pay. | |
38 */ | |
39 | |
40 be_trapped(th, tc) | |
41 register struct thing *th; | |
42 register coord *tc; | |
43 { | |
44 register struct trap *tp; | |
45 register char ch; | |
46 register const char *mname = NULL; | |
47 register bool is_player = (th == &player), | |
48 can_see; | |
49 register struct linked_list *mitem = NULL; | |
50 | |
51 | |
52 /* Can the player see the creature? */ | |
53 can_see = (cansee(tc->y, tc->x) && (is_player || !invisible(th))); | |
54 | |
55 tp = trap_at(tc->y, tc->x); | |
56 /* | |
57 * if he's wearing boots of elvenkind, he won't set off the trap | |
58 * unless its a magic pool (they're not really traps) | |
59 */ | |
60 if (is_player && | |
61 cur_misc[WEAR_BOOTS] != NULL && | |
62 cur_misc[WEAR_BOOTS]->o_which == MM_ELF_BOOTS && | |
63 tp->tr_type != POOL) | |
64 return '\0'; | |
65 | |
66 /* | |
67 * if the creature is flying then it won't set off the trap | |
68 */ | |
69 if (on(*th, ISFLY)) | |
70 return '\0'; | |
71 | |
72 tp->tr_flags |= ISFOUND; | |
73 | |
74 if (!is_player) { | |
75 mitem = find_mons(th->t_pos.y, th->t_pos.x); | |
76 mname = monsters[th->t_index].m_name; | |
77 } | |
78 else { | |
79 count = running = FALSE; | |
80 mvwaddch(cw, tp->tr_pos.y, tp->tr_pos.x, tp->tr_type); | |
81 } | |
82 switch (ch = tp->tr_type) { | |
83 case TRAPDOOR: | |
84 if (is_player) { | |
85 level++; | |
86 pstats.s_hpt -= roll(1, 10); | |
87 msg("You fell into a trap!"); | |
88 if (pstats.s_hpt <= 0) death(D_FALL); | |
89 new_level(NORMLEV); | |
90 } | |
91 else { | |
92 if (can_see) msg("The %s fell into a trap!", mname); | |
93 | |
94 /* See if the fall killed the monster */ | |
95 if ((th->t_stats.s_hpt -= roll(1, 10)) <= 0) { | |
96 killed(mitem, FALSE, FALSE); | |
97 } | |
98 else { /* Just move monster to next level */ | |
99 check_residue(th); | |
100 | |
101 /* Erase the monster from the old position */ | |
102 if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x))) | |
103 mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch); | |
104 mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' '); | |
105 turn_on(*th, ISELSEWHERE); | |
106 detach(mlist, mitem); | |
107 attach(tlist, mitem); /* remember him next level */ | |
108 } | |
109 } | |
110 when BEARTRAP: | |
111 if (is_stealth(th)) { | |
112 if (is_player) msg("You pass a bear trap."); | |
113 else if (can_see) msg("The %s passes a bear trap.", mname); | |
114 } | |
115 else { | |
116 th->t_no_move += BEARTIME; | |
117 if (is_player) msg("You are caught in a bear trap."); | |
118 else if (can_see) msg("The %s is caught in a bear trap.", | |
119 mname); | |
120 } | |
121 when SLEEPTRAP: | |
122 if (is_player) { | |
123 msg("A strange white mist envelops you."); | |
124 if (!ISWEARING(R_ALERT)) { | |
125 msg("You fall asleep."); | |
126 no_command += SLEEPTIME; | |
127 } | |
128 } | |
129 else { | |
130 if (can_see) | |
131 msg("A strange white mist envelops the %s.",mname); | |
132 if (on(*th, ISUNDEAD)) { | |
133 if (can_see) | |
134 msg("The mist doesn't seem to affect the %s.",mname); | |
135 } | |
136 else { | |
137 th->t_no_move += SLEEPTIME; | |
138 } | |
139 } | |
140 when ARROWTRAP: | |
141 if (swing(th->t_ctype, th->t_stats.s_lvl-1, th->t_stats.s_arm, 1)) | |
142 { | |
143 if (is_player) { | |
144 msg("Oh no! An arrow shot you."); | |
145 if ((pstats.s_hpt -= roll(1, 6)) <= 0) { | |
146 msg("The arrow killed you."); | |
147 death(D_ARROW); | |
148 } | |
149 } | |
150 else { | |
151 if (can_see) msg("An arrow shot the %s.", mname); | |
152 if ((th->t_stats.s_hpt -= roll(1, 6)) <= 0) { | |
153 if (can_see) msg("The arrow killed the %s.", mname); | |
154 killed(mitem, FALSE, FALSE); | |
155 } | |
156 } | |
157 } | |
158 else | |
159 { | |
160 register struct linked_list *item; | |
161 register struct object *arrow; | |
162 | |
163 if (is_player) msg("An arrow shoots past you."); | |
164 else if (can_see) msg("An arrow shoots by the %s.", mname); | |
165 item = new_item(sizeof *arrow); | |
166 arrow = OBJPTR(item); | |
167 arrow->o_type = WEAPON; | |
168 arrow->contents = NULL; | |
169 arrow->o_which = ARROW; | |
170 arrow->o_hplus = rnd(3) - 1; | |
171 arrow->o_dplus = rnd(3) - 1; | |
172 init_weapon(arrow, ARROW); | |
173 arrow->o_count = 1; | |
174 arrow->o_pos = *tc; | |
175 arrow->o_mark[0] = '\0'; | |
176 fall(item, FALSE); | |
177 } | |
178 when TELTRAP: | |
179 if (is_player) teleport(); | |
180 else { | |
181 register int rm; | |
182 struct room *old_room; /* old room of monster */ | |
183 | |
184 /* | |
185 * Erase the monster from the old position | |
186 */ | |
187 if (isalpha(mvwinch(cw, th->t_pos.y, th->t_pos.x))) | |
188 mvwaddch(cw, th->t_pos.y, th->t_pos.x, th->t_oldch); | |
189 mvwaddch(mw, th->t_pos.y, th->t_pos.x, ' '); | |
190 /* | |
191 * check to see if room should go dark | |
192 */ | |
193 if (on(*th, HASFIRE)) { | |
194 old_room=roomin(&th->t_pos); | |
195 if (old_room != NULL) { | |
196 register struct linked_list *fire_item; | |
197 | |
198 for (fire_item = old_room->r_fires; fire_item != NULL; | |
199 fire_item = next(fire_item)) { | |
200 if (THINGPTR(fire_item) == th) { | |
201 detach(old_room->r_fires, fire_item); | |
202 destroy_item(fire_item); | |
203 | |
204 if (old_room->r_fires == NULL) { | |
205 old_room->r_flags &= ~HASFIRE; | |
206 if (can_see) light(&hero); | |
207 } | |
208 } | |
209 } | |
210 } | |
211 } | |
212 | |
213 /* Get a new position */ | |
214 do { | |
215 rm = rnd_room(); | |
216 rnd_pos(&rooms[rm], &th->t_pos); | |
217 } until(winat(th->t_pos.y, th->t_pos.x) == FLOOR); | |
218 | |
219 /* Put it there */ | |
220 mvwaddch(mw, th->t_pos.y, th->t_pos.x, th->t_type); | |
221 th->t_oldch = CCHAR( mvwinch(cw, th->t_pos.y, th->t_pos.x) ); | |
222 /* | |
223 * check to see if room that creature appears in should | |
224 * light up | |
225 */ | |
226 if (on(*th, HASFIRE)) { | |
227 register struct linked_list *fire_item; | |
228 | |
229 fire_item = creat_item(); | |
230 ldata(fire_item) = (char *) th; | |
231 attach(rooms[rm].r_fires, fire_item); | |
232 | |
233 rooms[rm].r_flags |= HASFIRE; | |
234 if(cansee(th->t_pos.y, th->t_pos.x) && | |
235 next(rooms[rm].r_fires) == NULL) | |
236 light(&hero); | |
237 } | |
238 if (can_see) msg("The %s seems to have disappeared!", mname); | |
239 } | |
240 when DARTTRAP: | |
241 if (swing(th->t_ctype, th->t_stats.s_lvl+1, th->t_stats.s_arm, 1)) { | |
242 if (is_player) { | |
243 msg("A small dart just hit you in the shoulder."); | |
244 if ((pstats.s_hpt -= roll(1, 4)) <= 0) { | |
245 msg("The dart killed you."); | |
246 death(D_DART); | |
247 } | |
248 | |
249 /* Now the poison */ | |
250 if (!save(VS_POISON, &player, 0)) { | |
251 /* 75% chance it will do point damage - else strength */ | |
252 if (rnd(100) < 75) { | |
253 pstats.s_hpt /= 2; | |
254 if (pstats.s_hpt == 0) death(D_POISON); | |
255 } | |
256 else if (!ISWEARING(R_SUSABILITY)) | |
257 chg_str(-1); | |
258 } | |
259 } | |
260 else { | |
261 if (can_see) | |
262 msg("A small dart just hit the %s in the shoulder.", | |
263 mname); | |
264 if ((th->t_stats.s_hpt -= roll(1,4)) <= 0) { | |
265 if (can_see) msg("The dart killed the %s.", mname); | |
266 killed(mitem, FALSE, FALSE); | |
267 } | |
268 if (!save(VS_POISON, th, 0)) { | |
269 th->t_stats.s_hpt /= 2; | |
270 if (th->t_stats.s_hpt <= 0) { | |
271 if (can_see) msg("The dart killed the %s.", mname); | |
272 killed(mitem, FALSE, FALSE); | |
273 } | |
274 } | |
275 } | |
276 } | |
277 else { | |
278 if (is_player) | |
279 msg("A small dart whizzes by your ear and vanishes."); | |
280 else if (can_see) | |
281 msg("A small dart whizzes by the %s's ear and vanishes.", | |
282 mname); | |
283 } | |
284 when POOL: { | |
285 register int i; | |
286 | |
287 i = rnd(100); | |
288 if (is_player) { | |
289 if ((tp->tr_flags & ISGONE)) { | |
290 if (i < 30) { | |
291 teleport(); /* teleport away */ | |
292 pool_teleport = TRUE; | |
293 } | |
294 else if((i < 45) && level > 2) { | |
295 level -= rnd(2) + 1; | |
296 cur_max = level; | |
297 new_level(NORMLEV); | |
298 pool_teleport = TRUE; | |
299 msg("You here a faint groan from below."); | |
300 } | |
301 else if(i < 70) { | |
302 level += rnd(4) + 1; | |
303 new_level(NORMLEV); | |
304 pool_teleport = TRUE; | |
305 msg("You find yourself in strange surroundings."); | |
306 } | |
307 else if(i > 95) { | |
308 msg("Oh no!!! You drown in the pool!!! --More--"); | |
309 wait_for(cw,' '); | |
310 death(D_DROWN); | |
311 } | |
312 } | |
313 } | |
314 else { | |
315 if (i < 60) { | |
316 if (can_see) { | |
317 /* Drowns */ | |
318 if (i < 30) msg("The %s drowned in the pool!", mname); | |
319 | |
320 /* Teleported to another level */ | |
321 else msg("The %s disappeared!", mname); | |
322 } | |
323 killed(mitem, FALSE, FALSE); | |
324 } | |
325 } | |
326 } | |
327 when MAZETRAP: | |
328 if (is_player) { | |
329 pstats.s_hpt -= roll(1, 10); | |
330 level++; | |
331 msg("You fell through a trap door!"); | |
332 if (pstats.s_hpt <= 0) death(D_FALL); | |
333 new_level(MAZELEV); | |
334 msg("You are surrounded by twisty passages!"); | |
335 } | |
336 else { | |
337 if (can_see) msg("The %s fell into a trap!", mname); | |
338 killed(mitem, FALSE, FALSE); | |
339 } | |
340 } | |
341 | |
342 /* Move the cursor back onto the hero */ | |
343 wmove(cw, hero.y, hero.x); | |
344 | |
345 md_flushinp(); /* flush typeahead */ | |
346 | |
347 return(ch); | |
348 } | |
349 | |
350 /* | |
351 * blue_light: | |
352 * magically light up a room (or level or make it dark) | |
353 */ | |
354 | |
355 bool | |
356 blue_light(blessed, cursed) | |
357 bool blessed, cursed; | |
358 { | |
359 register struct room *rp; | |
360 bool ret_val=FALSE; /* Whether or not affect is known */ | |
361 | |
362 rp = roomin(&hero); /* What room is hero in? */ | |
363 | |
364 /* Darken the room if the magic is cursed */ | |
365 if (cursed) { | |
366 if ((rp == NULL) || !lit_room(rp)) msg(nothing); | |
367 else { | |
368 rp->r_flags |= ISDARK; | |
369 if (!lit_room(rp) && (levtype != OUTSIDE || !daytime)) | |
370 msg("The %s suddenly goes dark.", | |
371 levtype == OUTSIDE ? "area" : "room"); | |
372 else msg(nothing); | |
373 ret_val = TRUE; | |
374 } | |
375 } | |
376 else { | |
377 ret_val = TRUE; | |
378 if (rp && !lit_room(rp) && | |
379 (levtype != OUTSIDE || !daytime)) { | |
380 addmsg("The %s is lit", levtype == OUTSIDE ? "area" : "room"); | |
381 if (!terse) | |
382 addmsg(" by a %s blue light.", | |
383 blessed ? "bright" : "shimmering"); | |
384 endmsg(); | |
385 } | |
386 else if (winat(hero.y, hero.x) == PASSAGE) | |
387 msg("The corridor glows %sand then fades", | |
388 blessed ? "brightly " : ""); | |
389 else { | |
390 ret_val = FALSE; | |
391 msg(nothing); | |
392 } | |
393 if (blessed) { | |
394 register int i; /* Index through rooms */ | |
395 | |
396 for (i=0; i<MAXROOMS; i++) | |
397 rooms[i].r_flags &= ~ISDARK; | |
398 } | |
399 else if (rp) rp->r_flags &= ~ISDARK; | |
400 } | |
401 | |
402 /* | |
403 * Light the room and put the player back up | |
404 */ | |
405 light(&hero); | |
406 mvwaddch(cw, hero.y, hero.x, PLAYER); | |
407 return(ret_val); | |
408 } | |
409 | |
410 /* | |
411 * corr_move: | |
412 * Check to see that a move is legal. If so, return correct character. | |
413 * If not, if player came from a legal place, then try to turn him. | |
414 */ | |
415 | |
416 corr_move(dy, dx) | |
417 int dy, dx; | |
418 { | |
419 int legal=0; /* Number of legal alternatives */ | |
420 register int y, x, /* Indexes though possible positions */ | |
421 locy = 0, locx = 0; /* Hold delta of chosen location */ | |
422 | |
423 /* New position */ | |
424 nh.y = hero.y + dy; | |
425 nh.x = hero.x + dx; | |
426 | |
427 /* If it is a legal move, just return */ | |
428 if (nh.x >= 0 && nh.x < COLS && nh.y > 0 && nh.y < LINES - 2) { | |
429 | |
430 switch (winat(nh.y, nh.x)) { | |
431 case WALL: | |
432 case '|': | |
433 case '-': | |
434 break; | |
435 default: | |
436 if (diag_ok(&hero, &nh, &player)) | |
437 return; | |
438 } | |
439 } | |
440 | |
441 /* Check legal places surrounding the player -- ignore previous position */ | |
442 for (y = hero.y - 1; y <= hero.y + 1; y++) { | |
443 if (y < 1 || y > LINES - 3) | |
444 continue; | |
445 for (x = hero.x - 1; x <= hero.x + 1; x++) { | |
446 /* Ignore borders of the screen */ | |
447 if (x < 0 || x > COLS - 1) | |
448 continue; | |
449 | |
450 /* | |
451 * Ignore where we came from, where we are, and where we couldn't go | |
452 */ | |
453 if ((x == hero.x - dx && y == hero.y - dy) || | |
454 (x == hero.x + dx && y == hero.y + dy) || | |
455 (x == hero.x && y == hero.y)) | |
456 continue; | |
457 | |
458 switch (winat(y, x)) { | |
459 case WALL: | |
460 case '|': | |
461 case '-': | |
462 break; | |
463 default: | |
464 nh.y = y; | |
465 nh.x = x; | |
466 if (diag_ok(&hero, &nh, &player)) { | |
467 legal++; | |
468 locy = y - (hero.y - 1); | |
469 locx = x - (hero.x - 1); | |
470 } | |
471 } | |
472 } | |
473 } | |
474 | |
475 /* If we have 2 or more legal moves, make no change */ | |
476 if (legal != 1) { | |
477 return; | |
478 } | |
479 | |
480 runch = Moves[locy][locx]; | |
481 | |
482 /* | |
483 * For mazes, pretend like it is the beginning of a new run at each turn | |
484 * in order to get the lighting correct. | |
485 */ | |
486 if (levtype == MAZELEV) firstmove = TRUE; | |
487 return; | |
488 } | |
489 | |
490 /* | |
491 * dip_it: | |
492 * Dip an object into a magic pool | |
493 */ | |
494 dip_it() | |
495 { | |
496 reg struct linked_list *what; | |
497 reg struct object *ob; | |
498 reg struct trap *tp; | |
499 reg int wh, i; | |
500 | |
501 tp = trap_at(hero.y,hero.x); | |
502 if (tp == NULL || tp->tr_type != POOL) { | |
503 msg("I see no shimmering pool here"); | |
504 return; | |
505 } | |
506 if (tp->tr_flags & ISGONE) { | |
507 msg("This shimmering pool appears to have used once already"); | |
508 return; | |
509 } | |
510 if ((what = get_item(pack, "dip", ALL)) == NULL) { | |
511 msg(""); | |
512 after = FALSE; | |
513 return; | |
514 } | |
515 ob = OBJPTR(what); | |
516 mpos = 0; | |
517 if (ob == cur_armor || | |
518 ob == cur_misc[WEAR_BOOTS] || ob == cur_misc[WEAR_JEWEL] || | |
519 ob == cur_misc[WEAR_GAUNTLET]|| ob == cur_misc[WEAR_CLOAK] || | |
520 ob == cur_misc[WEAR_BRACERS] || ob == cur_misc[WEAR_NECKLACE]|| | |
521 ob == cur_ring[LEFT_1] || ob == cur_ring[LEFT_2] || | |
522 ob == cur_ring[LEFT_3] || ob == cur_ring[LEFT_4] || | |
523 ob == cur_ring[RIGHT_1] || ob == cur_ring[RIGHT_2] || | |
524 ob == cur_ring[RIGHT_3] || ob == cur_ring[RIGHT_4]) { | |
525 msg("You'll have to take it off first."); | |
526 return; | |
527 } | |
528 tp->tr_flags |= ISGONE; | |
529 if (ob != NULL) { | |
530 wh = ob->o_which; | |
531 ob->o_flags |= ISKNOW; | |
532 i = rnd(100); | |
533 switch(ob->o_type) { | |
534 case WEAPON: | |
535 if(i < 50) { /* enchant weapon here */ | |
536 if ((ob->o_flags & ISCURSED) == 0) { | |
537 ob->o_hplus += 1; | |
538 ob->o_dplus += 1; | |
539 } | |
540 else { /* weapon was prev cursed here */ | |
541 ob->o_hplus = rnd(2); | |
542 ob->o_dplus = rnd(2); | |
543 } | |
544 ob->o_flags &= ~ISCURSED; | |
545 msg("The %s glows blue for a moment.",weaps[wh].w_name); | |
546 } | |
547 else if(i < 70) { /* curse weapon here */ | |
548 if ((ob->o_flags & ISCURSED) == 0) { | |
549 ob->o_hplus = -(rnd(2)+1); | |
550 ob->o_dplus = -(rnd(2)+1); | |
551 } | |
552 else { /* if already cursed */ | |
553 ob->o_hplus--; | |
554 ob->o_dplus--; | |
555 } | |
556 ob->o_flags |= ISCURSED; | |
557 msg("The %s glows red for a moment.",weaps[wh].w_name); | |
558 } | |
559 else | |
560 msg(nothing); | |
561 when ARMOR: | |
562 if (i < 50) { /* enchant armor */ | |
563 if((ob->o_flags & ISCURSED) == 0) | |
564 ob->o_ac -= rnd(2) + 1; | |
565 else | |
566 ob->o_ac = -rnd(3)+ armors[wh].a_class; | |
567 ob->o_flags &= ~ISCURSED; | |
568 msg("The %s glows blue for a moment",armors[wh].a_name); | |
569 } | |
570 else if(i < 75){ /* curse armor */ | |
571 if ((ob->o_flags & ISCURSED) == 0) | |
572 ob->o_ac = rnd(3)+ armors[wh].a_class; | |
573 else | |
574 ob->o_ac += rnd(2) + 1; | |
575 ob->o_flags |= ISCURSED; | |
576 msg("The %s glows red for a moment.",armors[wh].a_name); | |
577 } | |
578 else | |
579 msg(nothing); | |
580 when STICK: { | |
581 int j; | |
582 j = rnd(8) + 1; | |
583 if(i < 50) { /* add charges */ | |
584 ob->o_charges += j; | |
585 ws_know[wh] = TRUE; | |
586 if (ob->o_flags & ISCURSED) | |
587 ob->o_flags &= ~ISCURSED; | |
588 sprintf(outstring,"The %s %s glows blue for a moment.", | |
589 ws_made[wh],ws_type[wh]); | |
590 msg(outstring); | |
591 } | |
592 else if(i < 65) { /* remove charges */ | |
593 if ((ob->o_charges -= i) < 0) | |
594 ob->o_charges = 0; | |
595 ws_know[wh] = TRUE; | |
596 if (ob->o_flags & ISBLESSED) | |
597 ob->o_flags &= ~ISBLESSED; | |
598 else | |
599 ob->o_flags |= ISCURSED; | |
600 sprintf(outstring,"The %s %s glows red for a moment.", | |
601 ws_made[wh],ws_type[wh]); | |
602 msg(outstring); | |
603 } | |
604 else | |
605 msg(nothing); | |
606 } | |
607 when SCROLL: | |
608 s_know[wh] = TRUE; | |
609 msg("The '%s' scroll unfurls.",s_names[wh]); | |
610 when POTION: | |
611 p_know[wh] = TRUE; | |
612 msg("The %s potion bubbles for a moment.",p_colors[wh]); | |
613 when RING: | |
614 if(i < 50) { /* enchant ring */ | |
615 if ((ob->o_flags & ISCURSED) == 0) | |
616 ob->o_ac += rnd(2) + 1; | |
617 else | |
618 ob->o_ac = rnd(2) + 1; | |
619 ob->o_flags &= ~ISCURSED; | |
620 } | |
621 else if(i < 80) { /* curse ring */ | |
622 if ((ob->o_flags & ISCURSED) == 0) | |
623 ob->o_ac = -(rnd(2) + 1); | |
624 else | |
625 ob->o_ac -= (rnd(2) + 1); | |
626 ob->o_flags |= ISCURSED; | |
627 } | |
628 r_know[wh] = TRUE; | |
629 msg("The %s ring vibrates for a moment.",r_stones[wh]); | |
630 when MM: | |
631 m_know[wh] = TRUE; | |
632 switch (ob->o_which) { | |
633 case MM_BRACERS: | |
634 case MM_PROTECT: | |
635 if(i < 50) { /* enchant item */ | |
636 if ((ob->o_flags & ISCURSED) == 0) | |
637 ob->o_ac += rnd(2) + 1; | |
638 else | |
639 ob->o_ac = rnd(2) + 1; | |
640 ob->o_flags &= ~ISCURSED; | |
641 } | |
642 else if(i < 80) { /* curse item */ | |
643 if ((ob->o_flags & ISCURSED) == 0) | |
644 ob->o_ac = -(rnd(2) + 1); | |
645 else | |
646 ob->o_ac -= (rnd(2) + 1); | |
647 ob->o_flags |= ISCURSED; | |
648 } | |
649 msg("The item vibrates for a moment."); | |
650 when MM_CHOKE: | |
651 case MM_DISAPPEAR: | |
652 ob->o_ac = 0; | |
653 msg ("The dust dissolves in the pool!"); | |
654 } | |
655 otherwise: | |
656 msg("The pool bubbles for a moment."); | |
657 } | |
658 updpack(FALSE); | |
659 } | |
660 else | |
661 msg(nothing); | |
662 } | |
663 | |
664 /* | |
665 * do_move: | |
666 * Check to see that a move is legal. If it is handle the | |
667 * consequences (fighting, picking up, etc.) | |
668 */ | |
669 | |
670 do_move(dy, dx) | |
671 int dy, dx; | |
672 { | |
673 register struct room *rp, *orp; | |
674 register char ch; | |
675 coord old_hero; | |
676 int i, wasfirstmove; | |
677 | |
678 wasfirstmove = firstmove; | |
679 firstmove = FALSE; | |
680 curprice = -1; /* if in trading post, we've moved off obj */ | |
681 if (player.t_no_move) { | |
682 player.t_no_move--; | |
683 msg("You are still stuck in the bear trap"); | |
684 return; | |
685 } | |
686 /* | |
687 * Do a confused move (maybe) | |
688 */ | |
689 if ((on(player, ISHUH) && rnd(100) < 80) || | |
690 (on(player, ISDANCE) && rnd(100) < 80) || | |
691 (ISWEARING(R_DELUSION) && rnd(100) < 25)) | |
692 nh = *rndmove(&player); | |
693 else { | |
694 nh.y = hero.y + dy; | |
695 nh.x = hero.x + dx; | |
696 } | |
697 | |
698 /* | |
699 * Check if he tried to move off the screen or make an illegal | |
700 * diagonal move, and stop him if he did. | |
701 */ | |
702 if (nh.x < 0 || nh.x > COLS-1 || nh.y < 1 || nh.y >= LINES - 2 | |
703 || !diag_ok(&hero, &nh, &player)) | |
704 { | |
705 after = running = FALSE; | |
706 return; | |
707 } | |
708 if (running && ce(hero, nh)) | |
709 after = running = FALSE; | |
710 ch = CCHAR( winat(nh.y, nh.x) ); | |
711 | |
712 /* Take care of hero trying to move close to something frightening */ | |
713 if (on(player, ISFLEE)) { | |
714 if (rnd(100) < 10) { | |
715 turn_off(player, ISFLEE); | |
716 msg("You regain your composure."); | |
717 } | |
718 else if (DISTANCE(nh.y, nh.x, player.t_dest->y, player.t_dest->x) < | |
719 DISTANCE(hero.y, hero.x, player.t_dest->y, player.t_dest->x)) | |
720 return; | |
721 } | |
722 | |
723 /* Take care of hero being held */ | |
724 if (on(player, ISHELD) && !isalpha(ch)) | |
725 { | |
726 msg("You are being held"); | |
727 return; | |
728 } | |
729 | |
730 /* assume he's not in a wall */ | |
731 if (!isalpha(ch)) turn_off(player, ISINWALL); | |
732 | |
733 switch(ch) { | |
734 case '|': | |
735 case '-': | |
736 if (levtype == OUTSIDE) { | |
737 hero = nh; | |
738 new_level(OUTSIDE); | |
739 return; | |
740 } | |
741 case WALL: | |
742 case SECRETDOOR: | |
743 if (off(player, CANINWALL) || running) { | |
744 after = running = FALSE; | |
745 | |
746 /* Light if finishing run */ | |
747 if (levtype == MAZELEV && lit_room(&rooms[0])) | |
748 look(FALSE, TRUE); | |
749 | |
750 after = running = FALSE; | |
751 | |
752 return; | |
753 } | |
754 turn_on(player, ISINWALL); | |
755 break; | |
756 case POOL: | |
757 if (levtype == OUTSIDE) { | |
758 lake_check(&nh); | |
759 running = FALSE; | |
760 break; | |
761 } | |
762 case MAZETRAP: | |
763 if (levtype == OUTSIDE) { | |
764 running = FALSE; | |
765 break; | |
766 } | |
767 case TRAPDOOR: | |
768 case TELTRAP: | |
769 case BEARTRAP: | |
770 case SLEEPTRAP: | |
771 case ARROWTRAP: | |
772 case DARTTRAP: | |
773 ch = be_trapped(&player, &nh); | |
774 if (ch == TRAPDOOR || ch == TELTRAP || | |
775 pool_teleport || ch == MAZETRAP) { | |
776 pool_teleport = FALSE; | |
777 return; | |
778 } | |
779 break; | |
780 case GOLD: | |
781 case POTION: | |
782 case SCROLL: | |
783 case FOOD: | |
784 case WEAPON: | |
785 case ARMOR: | |
786 case RING: | |
787 case MM: | |
788 case RELIC: | |
789 case STICK: | |
790 running = FALSE; | |
791 take = ch; | |
792 break; | |
793 case DOOR: | |
794 case STAIRS: | |
795 running = FALSE; | |
796 break; | |
797 case POST: | |
798 running = FALSE; | |
799 new_level(POSTLEV); | |
800 return; | |
801 default: | |
802 break; | |
803 } | |
804 | |
805 if (isalpha(ch)) { /* if its a monster then fight it */ | |
806 running = FALSE; | |
807 i = 1; | |
808 if (player.t_ctype == C_FIGHTER) | |
809 i += pstats.s_lvl/10; | |
810 while (i--) | |
811 fight(&nh, cur_weapon, FALSE); | |
812 return; | |
813 } | |
814 | |
815 /* | |
816 * if not fighting then move the hero | |
817 */ | |
818 old_hero = hero; /* Save hero's old position */ | |
819 hero = nh; /* Move the hero */ | |
820 rp = roomin(&hero); | |
821 orp = roomin(&old_hero); | |
822 | |
823 /* Unlight any possible cross-corridor */ | |
824 if (levtype == MAZELEV) { | |
825 register bool call_light = FALSE; | |
826 register char wall_check; | |
827 | |
828 if (wasfirstmove && lit_room(&rooms[0])) { | |
829 /* Are we moving out of a corridor? */ | |
830 switch (runch) { | |
831 case 'h': | |
832 case 'l': | |
833 if (old_hero.y + 1 < LINES - 2) { | |
834 wall_check = CCHAR( winat(old_hero.y + 1, old_hero.x) ); | |
835 if (!isrock(wall_check)) call_light = TRUE; | |
836 } | |
837 if (old_hero.y - 1 > 0) { | |
838 wall_check = CCHAR( winat(old_hero.y - 1, old_hero.x) ); | |
839 if (!isrock(wall_check)) call_light = TRUE; | |
840 } | |
841 break; | |
842 case 'j': | |
843 case 'k': | |
844 if (old_hero.x + 1 < COLS) { | |
845 wall_check = CCHAR( winat(old_hero.y, old_hero.x + 1) ); | |
846 if (!isrock(wall_check)) call_light = TRUE; | |
847 } | |
848 if (old_hero.x - 1 >= 0) { | |
849 wall_check = CCHAR( winat(old_hero.y, old_hero.x - 1) ); | |
850 if (!isrock(wall_check)) call_light = TRUE; | |
851 } | |
852 break; | |
853 default: | |
854 call_light = TRUE; | |
855 } | |
856 player.t_oldpos = old_hero; | |
857 if (call_light) light(&old_hero); | |
858 } | |
859 } | |
860 | |
861 else if (orp != NULL && rp == NULL) { /* Leaving a room -- darken it */ | |
862 orp->r_flags |= FORCEDARK; /* Fake darkness */ | |
863 light(&old_hero); | |
864 orp->r_flags &= ~FORCEDARK; /* Restore light state */ | |
865 } | |
866 else if (rp != NULL && orp == NULL){/* Entering a room */ | |
867 light(&hero); | |
868 } | |
869 ch = CCHAR( winat(old_hero.y, old_hero.x) ); | |
870 wmove(cw, unc(old_hero)); | |
871 waddch(cw, ch); | |
872 wmove(cw, unc(hero)); | |
873 waddch(cw, PLAYER); | |
874 } | |
875 | |
876 /* | |
877 * do_run: | |
878 * Start the hero running | |
879 */ | |
880 | |
881 do_run(ch) | |
882 char ch; | |
883 { | |
884 firstmove = TRUE; | |
885 running = TRUE; | |
886 after = FALSE; | |
887 runch = ch; | |
888 } | |
889 | |
890 /* | |
891 * getdelta: | |
892 * Takes a movement character (eg. h, j, k, l) and returns the | |
893 * y and x delta corresponding to it in the remaining arguments. | |
894 * Returns TRUE if it could find it, FALSE otherwise. | |
895 */ | |
896 bool | |
897 getdelta(match, dy, dx) | |
898 char match; | |
899 int *dy, *dx; | |
900 { | |
901 register y, x; | |
902 | |
903 for (y = 0; y < 3; y++) | |
904 for (x = 0; x < 3; x++) | |
905 if (Moves[y][x] == match) { | |
906 *dy = y - 1; | |
907 *dx = x - 1; | |
908 return(TRUE); | |
909 } | |
910 | |
911 return(FALSE); | |
912 } | |
913 | |
914 /* | |
915 * isatrap: | |
916 * Returns TRUE if this character is some kind of trap | |
917 */ | |
918 isatrap(ch) | |
919 reg char ch; | |
920 { | |
921 switch(ch) { | |
922 case DARTTRAP: | |
923 case TELTRAP: | |
924 case TRAPDOOR: | |
925 case ARROWTRAP: | |
926 case SLEEPTRAP: | |
927 case BEARTRAP: return(TRUE); | |
928 case MAZETRAP: | |
929 case POOL: return(levtype != OUTSIDE); | |
930 default: return(FALSE); | |
931 } | |
932 } | |
933 | |
934 /* | |
935 * Called to illuminate a room. | |
936 * If it is dark, remove anything that might move. | |
937 */ | |
938 | |
939 light(cp) | |
940 coord *cp; | |
941 { | |
942 register struct room *rp; | |
943 register int j, k, x, y; | |
944 register char ch, rch, sch; | |
945 register struct linked_list *item; | |
946 int jlow, jhigh, klow, khigh; /* Boundaries of lit area */ | |
947 | |
948 if ((rp = roomin(cp)) != NULL) { | |
949 /* | |
950 * is he wearing ring of illumination? | |
951 */ | |
952 if (&hero == cp && ISWEARING(R_LIGHT)) /* Must be hero's room */ | |
953 rp->r_flags &= ~ISDARK; | |
954 | |
955 /* If we are in a maze, don't look at the whole room (level) */ | |
956 if (levtype == MAZELEV) { | |
957 int see_radius; | |
958 | |
959 see_radius = 1; | |
960 | |
961 /* If we are looking at the hero in a rock, broaden our sights */ | |
962 if (&hero == cp || &player.t_oldpos == cp) { | |
963 ch = CCHAR( winat(hero.y, hero.x) ); | |
964 if (isrock(ch)) see_radius = 2; | |
965 ch = CCHAR( winat(player.t_oldpos.y, player.t_oldpos.x) ); | |
966 if (isrock(ch)) see_radius = 2; | |
967 } | |
968 | |
969 jlow = max(0, cp->y - see_radius - rp->r_pos.y); | |
970 jhigh = min(rp->r_max.y, cp->y + see_radius + 1 - rp->r_pos.y); | |
971 klow = max(0, cp->x - see_radius - rp->r_pos.x); | |
972 khigh = min(rp->r_max.x, cp->x + see_radius + 1 - rp->r_pos.x); | |
973 } | |
974 else { | |
975 jlow = klow = 0; | |
976 jhigh = rp->r_max.y; | |
977 khigh = rp->r_max.x; | |
978 } | |
979 for (j = 0; j < rp->r_max.y; j++) | |
980 { | |
981 for (k = 0; k < rp->r_max.x; k++) | |
982 { | |
983 bool see_here = 0, see_before = 0; | |
984 | |
985 /* Is this in the give area -- needed for maze */ | |
986 if ((j < jlow || j >= jhigh) && (k < klow || k >= khigh)) | |
987 continue; | |
988 | |
989 y = rp->r_pos.y + j; | |
990 x = rp->r_pos.x + k; | |
991 | |
992 /* | |
993 * If we are in a maze do not look at this area unless | |
994 * we can see it from where we are or where we last were | |
995 * (for erasing purposes). | |
996 */ | |
997 if (levtype == MAZELEV) { | |
998 /* If we can't see it from here, could we see it before? */ | |
999 if ((see_here = maze_view(y, x)) == FALSE) { | |
1000 coord savhero; | |
1001 | |
1002 /* Could we see it from where we were? */ | |
1003 savhero = hero; | |
1004 hero = player.t_oldpos; | |
1005 see_before = maze_view(y, x); | |
1006 hero = savhero; | |
1007 | |
1008 if (!see_before) continue; | |
1009 } | |
1010 } | |
1011 | |
1012 ch = show(y, x); | |
1013 wmove(cw, y, x); | |
1014 /* | |
1015 * Figure out how to display a secret door | |
1016 */ | |
1017 if (ch == SECRETDOOR) { | |
1018 if (j == 0 || j == rp->r_max.y - 1) | |
1019 ch = '-'; | |
1020 else | |
1021 ch = '|'; | |
1022 } | |
1023 /* For monsters, if they were previously not seen and | |
1024 * now can be seen, or vice-versa, make sure that will | |
1025 * happen. This is for dark rooms as opposed to invisibility. | |
1026 * | |
1027 * Call winat() in the test because ch will not reveal | |
1028 * invisible monsters. | |
1029 */ | |
1030 if (isalpha(winat(y, x))) { | |
1031 struct thing *tp; /* The monster */ | |
1032 | |
1033 item = wake_monster(y, x); | |
1034 tp = THINGPTR(item); | |
1035 | |
1036 /* Previously not seen -- now can see it */ | |
1037 if (tp->t_oldch == ' ' && cansee(tp->t_pos.y, tp->t_pos.x)) | |
1038 tp->t_oldch = CCHAR( mvinch(y, x) ); | |
1039 | |
1040 /* Previously seen -- now can't see it */ | |
1041 else if (!cansee(tp->t_pos.y, tp->t_pos.x) && | |
1042 roomin(&tp->t_pos) != NULL) | |
1043 switch (tp->t_oldch) { | |
1044 /* | |
1045 * Only blank it out if it is in a room and not | |
1046 * the border (or other wall) of the room. | |
1047 */ | |
1048 case DOOR: | |
1049 case SECRETDOOR: | |
1050 case '-': | |
1051 case '|': | |
1052 break; | |
1053 | |
1054 otherwise: | |
1055 tp->t_oldch = ' '; | |
1056 } | |
1057 } | |
1058 | |
1059 /* | |
1060 * If the room is a dark room, we might want to remove | |
1061 * monsters and the like from it (since they might | |
1062 * move). | |
1063 * A dark room. | |
1064 */ | |
1065 if ((!lit_room(rp) && (levtype != OUTSIDE)) || | |
1066 (levtype == OUTSIDE && !daytime) || | |
1067 on(player, ISBLIND) || | |
1068 (rp->r_flags & FORCEDARK) || | |
1069 (levtype == MAZELEV && !see_here && see_before)) { | |
1070 sch = CCHAR( mvwinch(cw, y, x) ); /* What's seen */ | |
1071 rch = CCHAR( mvinch(y, x) ); /* What's really there */ | |
1072 switch (rch) { | |
1073 case DOOR: | |
1074 case SECRETDOOR: | |
1075 case STAIRS: | |
1076 case TRAPDOOR: | |
1077 case TELTRAP: | |
1078 case BEARTRAP: | |
1079 case SLEEPTRAP: | |
1080 case ARROWTRAP: | |
1081 case DARTTRAP: | |
1082 case MAZETRAP: | |
1083 case POOL: | |
1084 case POST: | |
1085 case '|': | |
1086 case '-': | |
1087 case WALL: | |
1088 if (isalpha(sch)) ch = rch; | |
1089 else if (sch != FLOOR) ch = sch; | |
1090 else ch = ' '; /* Hide undiscoverd things */ | |
1091 when FLOOR: | |
1092 ch = ' '; | |
1093 otherwise: | |
1094 ch = ' '; | |
1095 } | |
1096 /* Take care of our magic bookkeeping. */ | |
1097 switch (sch) { | |
1098 case MAGIC: | |
1099 case BMAGIC: | |
1100 case CMAGIC: | |
1101 ch = sch; | |
1102 } | |
1103 } | |
1104 mvwaddch(cw, y, x, ch); | |
1105 } | |
1106 } | |
1107 } | |
1108 } | |
1109 | |
1110 /* | |
1111 * lit_room: | |
1112 * Called to see if the specified room is lit up or not. | |
1113 */ | |
1114 | |
1115 bool | |
1116 lit_room(rp) | |
1117 register struct room *rp; | |
1118 { | |
1119 register struct linked_list *fire_item; | |
1120 register struct thing *fire_creature; | |
1121 | |
1122 if (!(rp->r_flags & ISDARK)) return(TRUE); /* A definitely lit room */ | |
1123 | |
1124 /* Is it lit by fire light? */ | |
1125 if (rp->r_flags & HASFIRE) { | |
1126 switch (levtype) { | |
1127 case MAZELEV: | |
1128 /* See if a fire creature is in line of sight */ | |
1129 for (fire_item = rp->r_fires; fire_item != NULL; | |
1130 fire_item = next(fire_item)) { | |
1131 fire_creature = THINGPTR(fire_item); | |
1132 if (maze_view(fire_creature->t_pos.y, | |
1133 fire_creature->t_pos.x)) return(TRUE); | |
1134 } | |
1135 | |
1136 /* Couldn't find any in line-of-sight */ | |
1137 return(FALSE); | |
1138 | |
1139 /* We should probably do something special for the outside */ | |
1140 otherwise: | |
1141 return TRUE; | |
1142 } | |
1143 } | |
1144 return(FALSE); | |
1145 } | |
1146 | |
1147 /* | |
1148 * rndmove: | |
1149 * move in a random direction if the monster/person is confused | |
1150 */ | |
1151 | |
1152 coord * | |
1153 rndmove(who) | |
1154 struct thing *who; | |
1155 { | |
1156 register int x, y; | |
1157 register int ex, ey, nopen = 0; | |
1158 static coord ret; /* what we will be returning */ | |
1159 static coord dest; | |
1160 | |
1161 ret = who->t_pos; | |
1162 /* | |
1163 * Now go through the spaces surrounding the player and | |
1164 * set that place in the array to true if the space can be | |
1165 * moved into | |
1166 */ | |
1167 ey = ret.y + 1; | |
1168 ex = ret.x + 1; | |
1169 for (y = who->t_pos.y - 1; y <= ey; y++) | |
1170 if (y > 0 && y < LINES - 2) | |
1171 for (x = who->t_pos.x - 1; x <= ex; x++) | |
1172 { | |
1173 if (x < 0 || x >= COLS) | |
1174 continue; | |
1175 if (step_ok(y, x, NOMONST, who) == TRUE) | |
1176 { | |
1177 dest.y = y; | |
1178 dest.x = x; | |
1179 if (!diag_ok(&who->t_pos, &dest, who)) | |
1180 continue; | |
1181 if (rnd(++nopen) == 0) | |
1182 ret = dest; | |
1183 } | |
1184 } | |
1185 return &ret; | |
1186 } | |
1187 | |
1188 | |
1189 | |
1190 /* | |
1191 * set_trap: | |
1192 * set a trap at (y, x) on screen. | |
1193 */ | |
1194 | |
1195 set_trap(tp, y, x) | |
1196 register struct thing *tp; | |
1197 register int y, x; | |
1198 { | |
1199 register bool is_player = (tp == &player); | |
1200 register char selection = rnd(7) + '1'; | |
1201 register char ch = 0, och; | |
1202 int thief_bonus = 0; | |
1203 int s_dext; | |
1204 | |
1205 switch (och = CCHAR( mvinch(y, x) )) { | |
1206 case WALL: | |
1207 case FLOOR: | |
1208 case PASSAGE: | |
1209 break; | |
1210 default: | |
1211 msg("The trap failed!"); | |
1212 return; | |
1213 } | |
1214 | |
1215 if (is_player && player.t_ctype == C_THIEF) thief_bonus = 30; | |
1216 | |
1217 s_dext = (tp == &player) ? dex_compute() : tp->t_stats.s_dext; | |
1218 | |
1219 if (ntraps >= MAXTRAPS || ++trap_tries >= MAXTRPTRY || levtype == POSTLEV || | |
1220 rnd(80) >= (s_dext + tp->t_stats.s_lvl/2 + thief_bonus)) { | |
1221 if (is_player) msg("The trap failed!"); | |
1222 return; | |
1223 } | |
1224 | |
1225 | |
1226 if (is_player) { | |
1227 int state = 0; /* 0 -> current screen, 1 -> prompt screen, 2 -> done */ | |
1228 | |
1229 msg("Which kind of trap do you wish to set? (* for a list): "); | |
1230 do { | |
1231 selection = tolower(readchar()); | |
1232 switch (selection) { | |
1233 case '*': | |
1234 if (state != 1) { | |
1235 wclear(hw); | |
1236 touchwin(hw); | |
1237 mvwaddstr(hw, 2, 0, "[1] Trap Door\n[2] Bear Trap\n"); | |
1238 waddstr(hw, "[3] Sleep Trap\n[4] Arrow Trap\n"); | |
1239 waddstr(hw, "[5] Teleport Trap\n[6] Dart Trap\n"); | |
1240 if (wizard) { | |
1241 waddstr(hw, "[7] Magic pool\n[8] Maze Trap\n"); | |
1242 waddstr(hw, "[9] Trading Post\n"); | |
1243 } | |
1244 mvwaddstr(hw, 0, 0, "Which kind of trap do you wish to set? "); | |
1245 draw(hw); | |
1246 state = 1; /* Now in prompt window */ | |
1247 } | |
1248 break; | |
1249 | |
1250 case ESCAPE: | |
1251 if (state == 1) { | |
1252 clearok(cw, TRUE); /* Set up for redraw */ | |
1253 touchwin(cw); | |
1254 } | |
1255 msg(""); | |
1256 | |
1257 trap_tries--; /* Don't count this one */ | |
1258 after = FALSE; | |
1259 return; | |
1260 | |
1261 case '1': | |
1262 case '2': | |
1263 case '3': | |
1264 case '4': | |
1265 case '5': | |
1266 case '6': | |
1267 case '7': | |
1268 case '8': | |
1269 case '9': | |
1270 if (selection < '7' || wizard) { | |
1271 if (state == 1) { /* In prompt window */ | |
1272 clearok(cw, TRUE); /* Set up for redraw */ | |
1273 touchwin(cw); | |
1274 } | |
1275 | |
1276 msg(""); | |
1277 | |
1278 /* Make sure there is a floor below us for trap doors */ | |
1279 if (selection == '1' && level >= nfloors) { | |
1280 if (state == 1) draw(cw); | |
1281 msg("There is no level below this one."); | |
1282 return; | |
1283 } | |
1284 state = 2; /* Finished */ | |
1285 break; | |
1286 } | |
1287 | |
1288 /* Fall through for non-wizard, unusual trap case */ | |
1289 default: | |
1290 if (state == 1) { /* In the prompt window */ | |
1291 mvwaddstr(hw, 0, 0, "Please enter a selection between 1 and 6: "); | |
1292 draw(hw); | |
1293 } | |
1294 else { /* Normal window */ | |
1295 mpos = 0; | |
1296 msg("Please enter a selection between 1 and 6: "); | |
1297 } | |
1298 } | |
1299 } while (state != 2); | |
1300 } | |
1301 | |
1302 switch (selection) { | |
1303 case '1': ch = TRAPDOOR; | |
1304 when '2': ch = BEARTRAP; | |
1305 when '3': ch = SLEEPTRAP; | |
1306 when '4': ch = ARROWTRAP; | |
1307 when '5': ch = TELTRAP; | |
1308 when '6': ch = DARTTRAP; | |
1309 when '7': ch = POOL; | |
1310 when '8': ch = MAZETRAP; | |
1311 when '9': ch = POST; | |
1312 } | |
1313 | |
1314 mvaddch(y, x, ch); | |
1315 traps[ntraps].tr_show = och; | |
1316 traps[ntraps].tr_type = ch; | |
1317 traps[ntraps].tr_pos.y = y; | |
1318 traps[ntraps].tr_pos.x = x; | |
1319 if (is_player) | |
1320 traps[ntraps].tr_flags = ISTHIEFSET; | |
1321 if (ch == POOL || ch == POST) { | |
1322 traps[ntraps].tr_flags |= ISFOUND; | |
1323 } | |
1324 | |
1325 ntraps++; | |
1326 } | |
1327 | |
1328 /* | |
1329 * show: | |
1330 * returns what a certain thing will display as to the un-initiated | |
1331 */ | |
1332 | |
1333 show(y, x) | |
1334 register int y, x; | |
1335 { | |
1336 register char ch = CCHAR( winat(y, x) ); | |
1337 register struct linked_list *it; | |
1338 register struct thing *tp; | |
1339 | |
1340 if (isatrap(ch)) { | |
1341 register struct trap *trp = trap_at(y, x); | |
1342 | |
1343 return (trp->tr_flags & ISFOUND) ? ch : trp->tr_show; | |
1344 } | |
1345 else if (isalpha(ch)) { | |
1346 if ((it = find_mons(y, x)) == NULL) { | |
1347 msg("Can't find monster in show"); | |
1348 return(mvwinch(stdscr, y, x)); | |
1349 } | |
1350 tp = THINGPTR(it); | |
1351 | |
1352 if (on(*tp, ISDISGUISE)) ch = tp->t_disguise; /* As a mimic */ | |
1353 | |
1354 /* Hide invisible creatures */ | |
1355 else if (invisible(tp)) { | |
1356 /* We can't see surprise-type creatures through "see invisible" */ | |
1357 if (off(player,CANSEE) || on(*tp,CANSURPRISE)) | |
1358 ch = CCHAR( mvwinch(stdscr, y, x) ); /* Invisible */ | |
1359 } | |
1360 else if (on(*tp, CANINWALL)) { | |
1361 if (isrock(mvwinch(stdscr, y, x))) ch = CCHAR( winch(stdscr) ); /* As Xorn */ | |
1362 } | |
1363 } | |
1364 return ch; | |
1365 } | |
1366 | |
1367 | |
1368 /* | |
1369 * trap_at: | |
1370 * find the trap at (y,x) on screen. | |
1371 */ | |
1372 | |
1373 struct trap * | |
1374 trap_at(y, x) | |
1375 register int y, x; | |
1376 { | |
1377 register struct trap *tp, *ep; | |
1378 | |
1379 ep = &traps[ntraps]; | |
1380 for (tp = traps; tp < ep; tp++) | |
1381 if (tp->tr_pos.y == y && tp->tr_pos.x == x) | |
1382 break; | |
1383 if (tp == ep) | |
1384 debug((sprintf(prbuf, "Trap at %d,%d not in array", y, x), prbuf)); | |
1385 return tp; | |
1386 } |