Mercurial > hg > early-roguelike
comparison srogue/move.c @ 36:2128c7dc8a40
Import Super-Rogue 9.0 from the Roguelike Restoration Project (r1490)
author | elwin |
---|---|
date | Thu, 25 Nov 2010 12:21:41 +0000 |
parents | |
children | 94a0d9dd5ce1 |
comparison
equal
deleted
inserted
replaced
35:05018c63a721 | 36:2128c7dc8a40 |
---|---|
1 /* | |
2 * Hero movement commands | |
3 * | |
4 * @(#)move.c 9.0 (rdk) 7/17/84 | |
5 * | |
6 * Super-Rogue | |
7 * Copyright (C) 1984 Robert D. Kindelberger | |
8 * All rights reserved. | |
9 * | |
10 * Based on "Rogue: Exploring the Dungeons of Doom" | |
11 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman | |
12 * All rights reserved. | |
13 * | |
14 * See the file LICENSE.TXT for full copyright and licensing information. | |
15 */ | |
16 | |
17 #include <ctype.h> | |
18 #include "rogue.h" | |
19 #include "rogue.ext" | |
20 | |
21 /* | |
22 * Used to hold the new hero position | |
23 */ | |
24 | |
25 struct coord nh; | |
26 | |
27 /* | |
28 * do_run: | |
29 * Start the hero running | |
30 */ | |
31 | |
32 do_run(ch) | |
33 char ch; | |
34 { | |
35 running = TRUE; | |
36 after = FALSE; | |
37 runch = ch; | |
38 } | |
39 | |
40 /* | |
41 * do_move: | |
42 * Check to see that a move is legal. If it is handle the | |
43 * consequences (fighting, picking up, etc.) | |
44 */ | |
45 | |
46 do_move(dy, dx) | |
47 int dy, dx; | |
48 { | |
49 reg int ch; | |
50 reg struct room *rp; | |
51 | |
52 firstmove = FALSE; | |
53 curprice = -1; | |
54 inpool = FALSE; | |
55 | |
56 if (player.t_nomove > 0) { | |
57 player.t_nomove -= 1; | |
58 msg("You are still stuck in the bear trap."); | |
59 return; | |
60 } | |
61 /* | |
62 * Do a confused move (maybe) | |
63 */ | |
64 if ((rnd(100) < 80 && pl_on(ISHUH)) || | |
65 (iswearing(R_DELUS) && rnd(100) < 25)) | |
66 nh = *rndmove(&player); | |
67 else { | |
68 nh.y = hero.y + dy; | |
69 nh.x = hero.x + dx; | |
70 } | |
71 /* | |
72 * Check if he tried to move off the screen or make | |
73 * an illegal diagonal move, and stop him if he did. | |
74 */ | |
75 if (!cordok(nh.y, nh.x) || | |
76 (pl_off(ISETHER) && !diag_ok(&hero, &nh))) { | |
77 after = running = FALSE; | |
78 return; | |
79 } | |
80 if (running) { | |
81 ch = winat(nh.y, nh.x); | |
82 if (dead_end(ch)) { | |
83 reg int gox, goy, apsg, whichway; | |
84 | |
85 gox = goy = apsg = 0; | |
86 if (dy == 0) { | |
87 ch = show(hero.y+1,hero.x); | |
88 if (ch == PASSAGE) { | |
89 apsg += 1; | |
90 goy = 1; | |
91 } | |
92 ch = show(hero.y-1,hero.x); | |
93 if (ch == PASSAGE) { | |
94 apsg += 1; | |
95 goy = -1; | |
96 } | |
97 } | |
98 else if (dx == 0) { | |
99 ch = show(hero.y,hero.x+1); | |
100 if (ch == PASSAGE) { | |
101 gox = 1; | |
102 apsg += 1; | |
103 } | |
104 ch = show(hero.y,hero.x-1); | |
105 if (ch == PASSAGE) { | |
106 gox = -1; | |
107 apsg += 1; | |
108 } | |
109 } | |
110 if (apsg != 1) { | |
111 running = after = FALSE; | |
112 return; | |
113 } | |
114 else { /* can still run here */ | |
115 nh.y = hero.y + goy; | |
116 nh.x = hero.x + gox; | |
117 whichway = (goy + 1) * 3 + gox + 1; | |
118 switch(whichway) { | |
119 case 0: runch = 'y'; | |
120 when 1: runch = 'k'; | |
121 when 2: runch = 'u'; | |
122 when 3: runch = 'h'; | |
123 when 4: runch = '.'; /* shouldn't do */ | |
124 when 5: runch = 'l'; | |
125 when 6: runch = 'b'; | |
126 when 7: runch = 'j'; | |
127 when 8: runch = 'n'; | |
128 } | |
129 } | |
130 } | |
131 } | |
132 if (running && ce(hero, nh)) | |
133 after = running = FALSE; | |
134 ch = winat(nh.y, nh.x); | |
135 if (pl_on(ISHELD) && ch != 'F' && ch != 'd') { | |
136 msg("You are being held."); | |
137 return; | |
138 } | |
139 if (pl_off(ISETHER)) { | |
140 if (isatrap(ch)) { | |
141 ch = be_trapped(&nh, &player); | |
142 if (nlmove) { | |
143 nlmove = FALSE; | |
144 return; | |
145 } | |
146 else if (ch == POOL) | |
147 inpool = TRUE; | |
148 } | |
149 else if (dead_end(ch)) { | |
150 after = running = FALSE; | |
151 return; | |
152 } | |
153 else { | |
154 switch(ch) { | |
155 case GOLD: case POTION: case SCROLL: | |
156 case FOOD: case WEAPON: case ARMOR: | |
157 case RING: case AMULET: case STICK: | |
158 running = FALSE; | |
159 take = ch; | |
160 default: | |
161 if (illeg_ch(ch)) { | |
162 running = FALSE; | |
163 mvaddch(nh.y, nh.x, FLOOR); | |
164 teleport(rndspot, &player); | |
165 light(&nh); | |
166 msg("The spatial warp disappears !"); | |
167 return; | |
168 } | |
169 } | |
170 } | |
171 } | |
172 rp = roomin(&nh); | |
173 if (ch == DOOR) { /* just stepped on a door */ | |
174 running = FALSE; | |
175 if (rp != NULL && rf_on(rp, ISTREAS)) { | |
176 struct linked_list *item; | |
177 struct thing *tp; | |
178 | |
179 for (item = mlist; item != NULL; item = next(item)) { | |
180 tp = THINGPTR(item); | |
181 if (tp->t_room == rp) | |
182 runto(&tp->t_pos, &hero); | |
183 } | |
184 } | |
185 } | |
186 else if (ch == STAIRS && pl_off(ISETHER)) | |
187 running = FALSE; | |
188 else if (isalpha(ch) && pl_off(ISETHER)) { | |
189 running = FALSE; | |
190 fight(&nh, cur_weapon, FALSE); | |
191 return; | |
192 } | |
193 if (rp == NULL && player.t_room != NULL) | |
194 light(&hero); /* exiting a room */ | |
195 else if (rp != NULL && player.t_room == NULL) | |
196 light(&nh); /* just entering a room */ | |
197 if (pl_on(ISBLIND)) | |
198 ch = ' '; | |
199 else | |
200 ch = player.t_oldch; | |
201 mvwaddch(cw, hero.y, hero.x, ch); | |
202 mvwaddch(cw, nh.y, nh.x, PLAYER); | |
203 hero = nh; | |
204 player.t_room = rp; | |
205 player.t_oldch = mvinch(hero.y, hero.x); | |
206 } | |
207 | |
208 /* | |
209 * Called to illuminate a room. | |
210 * If it is dark, remove anything that might move. | |
211 */ | |
212 light(cp) | |
213 struct coord *cp; | |
214 { | |
215 reg struct room *rp; | |
216 reg int j, k, x, y; | |
217 reg char ch, rch; | |
218 reg struct linked_list *item; | |
219 | |
220 rp = roomin(cp); | |
221 if (rp == NULL) | |
222 return; | |
223 if (pl_on(ISBLIND)) { | |
224 for (j = 0; j < rp->r_max.y; j += 1) { | |
225 for (k = 0; k < rp->r_max.x; k += 1) { | |
226 y = rp->r_pos.y + j; | |
227 x = rp->r_pos.x + k; | |
228 mvwaddch(cw, y, x, ' '); | |
229 } | |
230 } | |
231 look(FALSE); | |
232 return; | |
233 } | |
234 if (iswearing(R_LIGHT)) | |
235 rp->r_flags &= ~ISDARK; | |
236 for (j = 0; j < rp->r_max.y; j += 1) { | |
237 for (k = 0; k < rp->r_max.x; k += 1) { | |
238 y = rp->r_pos.y + j; | |
239 x = rp->r_pos.x + k; | |
240 if (levtype == MAZELEV && !cansee(y, x)) | |
241 continue; | |
242 ch = show(y, x); | |
243 wmove(cw, y, x); | |
244 /* | |
245 * Figure out how to display a secret door | |
246 */ | |
247 if (ch == SECRETDOOR) { | |
248 if (j == 0 || j == rp->r_max.y - 1) | |
249 ch = '-'; | |
250 else | |
251 ch = '|'; | |
252 } | |
253 if (isalpha(ch)) { | |
254 struct thing *mit; | |
255 | |
256 item = wake_monster(y, x); | |
257 if (item == NULL) { | |
258 ch = FLOOR; | |
259 mvaddch(y, x, ch); | |
260 } | |
261 else { | |
262 mit = THINGPTR(item); | |
263 if (mit->t_oldch == ' ') | |
264 if (!rf_on(rp,ISDARK)) | |
265 mit->t_oldch = mvinch(y, x); | |
266 if (levtype == MAZELEV) | |
267 ch = mvinch(y, x); | |
268 } | |
269 } | |
270 if (rf_on(rp,ISDARK)) { | |
271 rch = mvwinch(cw, y, x); | |
272 if (isatrap(rch)) { | |
273 ch = rch; /* if its a trap */ | |
274 } | |
275 else { /* try other things */ | |
276 switch (rch) { | |
277 case DOOR: case STAIRS: case '|': | |
278 case '-': | |
279 ch = rch; | |
280 otherwise: | |
281 ch = ' '; | |
282 } | |
283 } | |
284 } | |
285 mvwaddch(cw, y, x, ch); | |
286 } | |
287 } | |
288 } | |
289 | |
290 /* | |
291 * show: | |
292 * returns what a certain thing will display as to the un-initiated | |
293 */ | |
294 show(y, x) | |
295 int y, x; | |
296 { | |
297 reg char ch = winat(y, x); | |
298 reg struct linked_list *it; | |
299 reg struct thing *tp; | |
300 reg struct trap *ta; | |
301 | |
302 if (isatrap(ch)) { | |
303 if ((ta = trap_at(y, x)) == NULL) | |
304 return FLOOR; | |
305 if (iswearing(R_FTRAPS)) | |
306 ta->tr_flags |= ISFOUND; | |
307 return ((ta->tr_flags & ISFOUND) ? ta->tr_type : FLOOR); | |
308 } | |
309 if (ch == SECRETDOOR && iswearing(R_FTRAPS)) { | |
310 mvaddch(y,x,DOOR); | |
311 return DOOR; | |
312 } | |
313 if ((it = find_mons(y, x)) != NULL) { /* maybe a monster */ | |
314 tp = THINGPTR(it); | |
315 if (ch == 'M' || (tp->t_flags & ISINVIS)) { | |
316 if (ch == 'M') | |
317 ch = tp->t_disguise; | |
318 else if (pl_off(CANSEE)) { | |
319 if (ch == 's') | |
320 ch = ' '; /* shadows show as a blank */ | |
321 else | |
322 ch = mvinch(y, x); /* hide invisibles */ | |
323 } | |
324 } | |
325 } | |
326 return ch; | |
327 } | |
328 | |
329 /* | |
330 * be_trapped: | |
331 * Hero or monster stepped on a trap. | |
332 */ | |
333 be_trapped(tc, th) | |
334 struct thing *th; | |
335 struct coord *tc; | |
336 { | |
337 reg struct trap *trp; | |
338 reg int ch, ishero; | |
339 struct linked_list *mon; | |
340 char stuckee[35], seeit, sayso; | |
341 | |
342 if ((trp = trap_at(tc->y, tc->x)) == NULL) | |
343 return; | |
344 ishero = (th == &player); | |
345 if (ishero) { | |
346 strcpy(stuckee, "You"); | |
347 count = running = FALSE; | |
348 } | |
349 else { | |
350 sprintf(stuckee, "The %s", monsters[th->t_indx].m_name); | |
351 } | |
352 seeit = cansee(tc->y, tc->x); | |
353 if (seeit) | |
354 mvwaddch(cw, tc->y, tc->x, trp->tr_type); | |
355 trp->tr_flags |= ISFOUND; | |
356 sayso = TRUE; | |
357 switch (ch = trp->tr_type) { | |
358 case POST: | |
359 if (ishero) { | |
360 nlmove = TRUE; | |
361 new_level(POSTLEV); | |
362 } | |
363 else | |
364 goto goner; | |
365 when MAZETRAP: | |
366 if (ishero) { | |
367 nlmove = TRUE; | |
368 level += 1; | |
369 new_level(MAZELEV); | |
370 msg("You are surrounded by twisty passages!"); | |
371 } | |
372 else | |
373 goto goner; | |
374 when TELTRAP: | |
375 nlmove = TRUE; | |
376 teleport(trp->tr_goto, th); | |
377 when TRAPDOOR: | |
378 if (ishero) { | |
379 level += 1; | |
380 new_level(NORMLEV); | |
381 } | |
382 else { /* monsters get lost */ | |
383 goner: | |
384 ch = GONER; | |
385 } | |
386 nlmove = TRUE; | |
387 if (seeit && sayso) | |
388 msg("%s fell into a trap!", stuckee); | |
389 when BEARTRAP: | |
390 th->t_nomove += BEARTIME; | |
391 if (seeit) { | |
392 strcat(stuckee, (ishero ? " are" : " is")); | |
393 msg("%s caught in a bear trap.", stuckee); | |
394 } | |
395 when SLEEPTRAP: | |
396 if (ishero && pl_on(ISINVINC)) | |
397 msg("You feel momentarily dizzy."); | |
398 else { | |
399 if (ishero) | |
400 th->t_nocmd += SLEEPTIME; | |
401 else | |
402 th->t_nomove += SLEEPTIME; | |
403 if (seeit) | |
404 msg("%s fall%s asleep in a strange white mist.", | |
405 stuckee, (ishero ? "":"s")); | |
406 } | |
407 when ARROWTRAP: { | |
408 int resist, ac; | |
409 struct stats *it; | |
410 | |
411 stuckee[0] = tolower(stuckee[0]); | |
412 it = &th->t_stats; | |
413 if (ishero && cur_armor != NULL) | |
414 ac = cur_armor->o_ac; | |
415 else | |
416 ac = it->s_arm; | |
417 resist = ac + getpdex(it, FALSE); | |
418 if (ishero && pl_on(ISINVINC)) | |
419 resist = -100; /* invincible is impossible to hit */ | |
420 if (swing(3 + (level / 4), resist, 1)) { | |
421 if (seeit) | |
422 msg("%sAn arrow shot %s.", (ishero ? "Oh no! " : ""), | |
423 stuckee); | |
424 if (ishero) | |
425 chg_hpt(-roll(1,6),FALSE,K_ARROW); | |
426 else { | |
427 it->s_hpt -= roll(1,6); | |
428 if (it->s_hpt < 1) { | |
429 sayso = FALSE; | |
430 goto goner; | |
431 } | |
432 } | |
433 } | |
434 else { | |
435 struct linked_list *item; | |
436 struct object *arrow; | |
437 | |
438 if (seeit) | |
439 msg("An arrow shoots past %s.", stuckee); | |
440 item = new_thing(FALSE, WEAPON, ARROW); | |
441 arrow = OBJPTR(item); | |
442 arrow->o_hplus = 3; | |
443 arrow->o_dplus = rnd(2); | |
444 arrow->o_count = 1; | |
445 arrow->o_pos = th->t_pos; | |
446 fall(item, FALSE); | |
447 } | |
448 } | |
449 when DARTTRAP: { | |
450 int resist, ac; | |
451 struct stats *it; | |
452 | |
453 stuckee[0] = tolower(stuckee[0]); | |
454 it = &th->t_stats; | |
455 if (ishero && cur_armor != NULL) | |
456 ac = cur_armor->o_ac; | |
457 else | |
458 ac = it->s_arm; | |
459 resist = ac + getpdex(it, FALSE); | |
460 if (ishero && pl_on(ISINVINC)) | |
461 resist = -100; /* invincible is impossible to hit */ | |
462 if (swing(3 + (level / 4), resist, 0)) { | |
463 if (seeit) | |
464 msg("A small dart just hit %s.", stuckee); | |
465 if (ishero) { | |
466 if (!save(VS_POISON)) | |
467 chg_abil(CON,-1,TRUE); | |
468 if (!iswearing(R_SUSTSTR)) | |
469 chg_abil(STR,-1,TRUE); | |
470 chg_hpt(-roll(1, 4),FALSE,K_DART); | |
471 } | |
472 else { | |
473 if (!save_throw(VS_POISON, th)) | |
474 it->s_ef.a_str -= 1; | |
475 it->s_hpt -= roll(1, 4); | |
476 if (it->s_hpt < 1) { | |
477 sayso = FALSE; | |
478 goto goner; | |
479 } | |
480 } | |
481 } | |
482 else if (seeit) | |
483 msg("A small dart whizzes by %s.", stuckee); | |
484 } | |
485 when POOL: | |
486 if (!ishero && rnd(100) < 10) { | |
487 if (seeit) | |
488 msg("The %s drowns !!", stuckee); | |
489 goto goner; | |
490 } | |
491 if ((trp->tr_flags & ISGONE) && rnd(100) < 10) { | |
492 nlmove = TRUE; | |
493 if (rnd(100) < 15) | |
494 teleport(rndspot); /* teleport away */ | |
495 else if(rnd(100) < 15 && level > 2) { | |
496 level -= rnd(2) + 1; | |
497 new_level(NORMLEV); | |
498 msg("You here a faint groan from below."); | |
499 } | |
500 else if(rnd(100) < 40) { | |
501 level += rnd(4); | |
502 new_level(NORMLEV); | |
503 msg("You find yourself in strange surroundings."); | |
504 } | |
505 else if(rnd(100) < 6 && pl_off(ISINVINC)) { | |
506 msg("Oh no!!! You drown in the pool!!! --More--"); | |
507 wait_for(cw, ' '); | |
508 death(K_POOL); | |
509 } | |
510 else | |
511 nlmove = FALSE; | |
512 } | |
513 } | |
514 flushinp(); /* flush typeahead */ | |
515 return ch; | |
516 } | |
517 | |
518 /* | |
519 * dip_it: | |
520 * Dip an object into a magic pool | |
521 */ | |
522 dip_it() | |
523 { | |
524 reg struct linked_list *what; | |
525 reg struct object *ob; | |
526 reg struct trap *tp; | |
527 reg int wh; | |
528 | |
529 tp = trap_at(hero.y,hero.x); | |
530 if (tp == NULL || inpool == FALSE || (tp->tr_flags & ISGONE)) | |
531 return; | |
532 | |
533 if ((what = get_item("dip",0)) == NULL) | |
534 return; | |
535 ob = OBJPTR(what); | |
536 mpos = 0; | |
537 /* | |
538 * If hero is trying to dip an object OTHER than his | |
539 * current weapon, make sure that he could drop his | |
540 * current weapon | |
541 */ | |
542 if (ob != cur_weapon) { | |
543 if (cur_weapon != NULL && o_on(cur_weapon, ISCURSED)) { | |
544 msg("You are unable to release your weapon."); | |
545 after = FALSE; | |
546 return; | |
547 } | |
548 } | |
549 if (ob == cur_armor) { | |
550 msg("You have to take off your armor before you can dip it."); | |
551 after = FALSE; | |
552 return; | |
553 } | |
554 else if (ob == cur_ring[LEFT] || ob == cur_ring[RIGHT]) { | |
555 msg("You have to take that ring off before you can dip it."); | |
556 after = FALSE; | |
557 return; | |
558 } | |
559 wh = ob->o_which; | |
560 tp->tr_flags |= ISGONE; | |
561 if (ob != NULL && o_off(ob,ISPROT)) { | |
562 setoflg(ob,ISKNOW); | |
563 switch(ob->o_type) { | |
564 case WEAPON: | |
565 if(rnd(100) < 20) { /* enchant weapon here */ | |
566 if (o_off(ob,ISCURSED)) { | |
567 ob->o_hplus += 1; | |
568 ob->o_dplus += 1; | |
569 } | |
570 else { /* weapon was prev cursed here */ | |
571 ob->o_hplus = rnd(2); | |
572 ob->o_dplus = rnd(2); | |
573 } | |
574 resoflg(ob,ISCURSED); | |
575 } | |
576 else if(rnd(100) < 10) { /* curse weapon here */ | |
577 if (o_off(ob,ISCURSED)) { | |
578 ob->o_hplus = -(rnd(2)+1); | |
579 ob->o_dplus = -(rnd(2)+1); | |
580 } | |
581 else { /* if already cursed */ | |
582 ob->o_hplus--; | |
583 ob->o_dplus--; | |
584 } | |
585 setoflg(ob,ISCURSED); | |
586 } | |
587 msg("The %s glows for a moment.",w_magic[wh].mi_name); | |
588 when ARMOR: | |
589 if (rnd(100) < 30) { /* enchant armor */ | |
590 if(o_off(ob,ISCURSED)) | |
591 ob->o_ac -= rnd(2) + 1; | |
592 else | |
593 ob->o_ac = -rnd(3)+ armors[wh].a_class; | |
594 resoflg(ob,ISCURSED); | |
595 } | |
596 else if(rnd(100) < 15){ /* curse armor */ | |
597 if (o_off(ob,ISCURSED)) | |
598 ob->o_ac = rnd(3)+ armors[wh].a_class; | |
599 else | |
600 ob->o_ac += rnd(2) + 1; | |
601 setoflg(ob,ISCURSED); | |
602 } | |
603 msg("The %s glows for a moment.",a_magic[wh].mi_name); | |
604 when STICK: { | |
605 int i; | |
606 struct rod *rd; | |
607 | |
608 i = rnd(8) + 1; | |
609 if(rnd(100) < 25) /* add charges */ | |
610 ob->o_charges += i; | |
611 else if(rnd(100) < 10) { /* remove charges */ | |
612 if ((ob->o_charges -= i) < 0) | |
613 ob->o_charges = 0; | |
614 } | |
615 ws_know[wh] = TRUE; | |
616 rd = &ws_stuff[wh]; | |
617 msg("The %s %s glows for a moment.",rd->ws_made,rd->ws_type); | |
618 } | |
619 when SCROLL: | |
620 s_know[wh] = TRUE; | |
621 msg("The '%s' scroll unfurls.",s_names[wh]); | |
622 when POTION: | |
623 p_know[wh] = TRUE; | |
624 msg("The %s potion bubbles for a moment.",p_colors[wh]); | |
625 when RING: | |
626 r_know[wh] = TRUE; | |
627 if (magring(ob)) { | |
628 if(rnd(100) < 25) { /* enchant ring */ | |
629 if (o_off(ob,ISCURSED)) | |
630 ob->o_ac += rnd(2) + 1; | |
631 else | |
632 ob->o_ac = rnd(2) + 1; | |
633 resoflg(ob,ISCURSED); | |
634 } | |
635 else if(rnd(100) < 10) { /* curse ring */ | |
636 if (o_off(ob,ISCURSED)) | |
637 ob->o_ac = -(rnd(2) + 1); | |
638 else | |
639 ob->o_ac -= (rnd(2) + 1); | |
640 setoflg(ob,ISCURSED); | |
641 } | |
642 } | |
643 msg("The %s ring vibrates for a moment.",r_stones[wh]); | |
644 otherwise: | |
645 msg("The pool bubbles for a moment."); | |
646 } | |
647 } | |
648 cur_weapon = ob; /* hero has to weild item to dip it */ | |
649 } | |
650 | |
651 | |
652 /* | |
653 * trap_at: | |
654 * Find the trap at (y,x) on screen. | |
655 */ | |
656 struct trap * | |
657 trap_at(y, x) | |
658 int y, x; | |
659 { | |
660 reg struct trap *tp, *ep; | |
661 | |
662 ep = &traps[ntraps]; | |
663 for (tp = traps; tp < ep; tp += 1) | |
664 if (tp->tr_pos.y == y && tp->tr_pos.x == x) | |
665 break; | |
666 if (tp >= ep) | |
667 tp = NULL; | |
668 return tp; | |
669 } | |
670 | |
671 /* | |
672 * rndmove: | |
673 * move in a random direction if the monster/person is confused | |
674 */ | |
675 struct coord * | |
676 rndmove(who) | |
677 struct thing *who; | |
678 { | |
679 reg int x, y, ex, ey, ch; | |
680 int nopen = 0; | |
681 struct linked_list *item; | |
682 static struct coord ret; /* what we will be returning */ | |
683 static struct coord dest; | |
684 | |
685 ret = who->t_pos; | |
686 /* | |
687 * Now go through the spaces surrounding the player and | |
688 * set that place in the array to true if the space can be | |
689 * moved into | |
690 */ | |
691 ey = ret.y + 1; | |
692 ex = ret.x + 1; | |
693 for (y = who->t_pos.y - 1; y <= ey; y += 1) { | |
694 for (x = who->t_pos.x - 1; x <= ex; x += 1) { | |
695 if (!cordok(y, x)) | |
696 continue; | |
697 ch = winat(y, x); | |
698 if (step_ok(ch)) { | |
699 dest.y = y; | |
700 dest.x = x; | |
701 if (!diag_ok(&who->t_pos, &dest)) | |
702 continue; | |
703 if (ch == SCROLL && who != &player) { | |
704 /* | |
705 * check for scare monster scrolls | |
706 */ | |
707 item = find_obj(y, x); | |
708 if (item != NULL && (OBJPTR(item))->o_which == S_SCARE) | |
709 continue; | |
710 } | |
711 if (rnd(++nopen) == 0) | |
712 ret = dest; | |
713 } | |
714 } | |
715 } | |
716 return &ret; | |
717 } | |
718 | |
719 /* | |
720 * isatrap: | |
721 * Returns TRUE if this character is some kind of trap | |
722 */ | |
723 isatrap(ch) | |
724 char ch; | |
725 { | |
726 switch(ch) { | |
727 case POST: | |
728 case DARTTRAP: | |
729 case POOL: | |
730 case TELTRAP: | |
731 case TRAPDOOR: | |
732 case ARROWTRAP: | |
733 case SLEEPTRAP: | |
734 case BEARTRAP: | |
735 case MAZETRAP: | |
736 return TRUE; | |
737 default: | |
738 return FALSE; | |
739 } | |
740 } |