comparison rogue4/chase.c @ 12:9535a08ddc39

Import Rogue 5.2 from the Roguelike Restoration Project (r1490)
author edwarj4
date Sat, 24 Oct 2009 16:52:52 +0000
parents
children 1b73a8641b37
comparison
equal deleted inserted replaced
11:949d558c2162 12:9535a08ddc39
1 /*
2 * Code for one creature to chase another
3 *
4 * @(#)chase.c 4.25 (Berkeley) 5/5/82
5 *
6 * Rogue: Exploring the Dungeons of Doom
7 * Copyright (C) 1980, 1981, 1982 Michael Toy, Ken Arnold and Glenn Wichman
8 * All rights reserved.
9 *
10 * See the file LICENSE.TXT for full copyright and licensing information.
11 */
12
13 #include <curses.h>
14 #include "rogue.h"
15
16 #define DRAGONSHOT 5 /* one chance in DRAGONSHOT that a dragon will flame */
17
18 coord ch_ret; /* Where chasing takes you */
19
20 /*
21 * runners:
22 * Make all the running monsters move.
23 */
24 runners()
25 {
26 register THING *tp;
27 register THING *ntp;
28
29 for (tp = mlist; tp != NULL; tp = ntp)
30 {
31 ntp = next(tp);
32 if (!on(*tp, ISHELD) && on(*tp, ISRUN))
33 {
34 if (!on(*tp, ISSLOW) || tp->t_turn)
35 if (do_chase(tp) == -1)
36 continue;
37 if (on(*tp, ISHASTE))
38 if (do_chase(tp) == -1)
39 continue;
40 tp->t_turn ^= TRUE;
41 }
42 }
43 }
44
45 /*
46 * do_chase:
47 * Make one thing chase another.
48 */
49 do_chase(th)
50 register THING *th;
51 {
52 register struct room *rer, *ree; /* room of chaser, room of chasee */
53 register int mindist = 32767, i, dist;
54 register bool stoprun = FALSE; /* TRUE means we are there */
55 register char sch;
56 register bool door;
57 register THING *obj;
58 register struct room *oroom;
59 coord this; /* Temporary destination for chaser */
60
61 rer = th->t_room; /* Find room of chaser */
62 if (on(*th, ISGREED) && rer->r_goldval == 0)
63 th->t_dest = &hero; /* If gold has been taken, run after hero */
64 if (th->t_dest == &hero) /* Find room of chasee */
65 ree = proom;
66 else
67 ree = roomin(th->t_dest);
68 /*
69 * We don't count doors as inside rooms for this routine
70 */
71 door = (chat(th->t_pos.y, th->t_pos.x) == DOOR);
72 /*
73 * If the object of our desire is in a different room,
74 * and we are not in a corridor, run to the door nearest to
75 * our goal.
76 */
77 over:
78 if (rer != ree)
79 {
80 for (i = 0; i < rer->r_nexits; i++) /* loop through doors */
81 {
82 dist = DISTANCE(th->t_dest->y, th->t_dest->x,
83 rer->r_exit[i].y, rer->r_exit[i].x);
84 if (dist < mindist)
85 {
86 this = rer->r_exit[i];
87 mindist = dist;
88 }
89 }
90 if (door)
91 {
92 rer = &passages[flat(th->t_pos.y, th->t_pos.x) & F_PNUM];
93 door = FALSE;
94 goto over;
95 }
96 }
97 else
98 {
99 this = *th->t_dest;
100 /*
101 * For dragons check and see if (a) the hero is on a straight
102 * line from it, and (b) that it is within shooting distance,
103 * but outside of striking range.
104 */
105 if (th->t_type == 'D' && (th->t_pos.y == hero.y || th->t_pos.x == hero.x
106 || abs(th->t_pos.y - hero.y) == abs(th->t_pos.x - hero.x))
107 && DISTANCE(th->t_pos.y, th->t_pos.x, hero.y, hero.x) <= BOLT_LENGTH * BOLT_LENGTH
108 && !on(*th, ISCANC) && rnd(DRAGONSHOT) == 0)
109 {
110 delta.y = sign(hero.y - th->t_pos.y);
111 delta.x = sign(hero.x - th->t_pos.x);
112 fire_bolt(&th->t_pos, &delta, "flame");
113 running = FALSE;
114 count = quiet = 0;
115 return 0;
116 }
117 }
118 /*
119 * This now contains what we want to run to this time
120 * so we run to it. If we hit it we either want to fight it
121 * or stop running
122 */
123 if (!chase(th, &this))
124 {
125 if (ce(this, hero))
126 {
127 return ( attack(th) );
128 }
129 else if (ce(this, *th->t_dest))
130 {
131 for (obj = lvl_obj; obj != NULL; obj = next(obj))
132 if (th->t_dest == &obj->o_pos)
133 {
134 detach(lvl_obj, obj);
135 attach(th->t_pack, obj);
136 chat(obj->o_pos.y, obj->o_pos.x) =
137 (th->t_room->r_flags & ISGONE) ? PASSAGE : FLOOR;
138 th->t_dest = find_dest(th);
139 break;
140 }
141 if (th->t_type != 'F')
142 stoprun = TRUE;
143 }
144 }
145 else if (th->t_type == 'F')
146 return(0);
147 mvaddch(th->t_pos.y, th->t_pos.x, th->t_oldch);
148 if (!ce(ch_ret, th->t_pos))
149 {
150 sch = mvinch(ch_ret.y, ch_ret.x);
151 if (sch == FLOOR && (th->t_room->r_flags & ISDARK)
152 && DISTANCE(th->t_pos.y, th->t_pos.x, hero.y, hero.x)
153 && !on(player, ISBLIND))
154 th->t_oldch = ' ';
155 else
156 th->t_oldch = sch;
157 oroom = th->t_room;
158 th->t_room = roomin(&ch_ret);
159 if (oroom != th->t_room)
160 th->t_dest = find_dest(th);
161
162 moat(th->t_pos.y, th->t_pos.x) = NULL;
163 moat(ch_ret.y, ch_ret.x) = th;
164 th->t_pos = ch_ret;
165 }
166 if (see_monst(th))
167 mvaddch(ch_ret.y, ch_ret.x, th->t_disguise);
168 else if (on(player, SEEMONST))
169 {
170 standout();
171 mvaddch(ch_ret.y, ch_ret.x, th->t_type);
172 standend();
173 }
174 /*
175 * And stop running if need be