comparison srogue/chase.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 * Code for one object to chase another
3 *
4 * @(#)chase.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 "rogue.h"
18 #include "rogue.ext"
19
20 #define FARAWAY 32767
21 #define RDIST(a, b) (DISTANCE((a)->y, (a)->x, (b).y, (b).x))
22
23 struct coord ch_ret; /* Where chasing takes you */
24
25 /*
26 * runners:
27 * Make all the running monsters move.
28 */
29 runners()
30 {
31 reg struct thing *tp;
32 reg struct linked_list *mon,*nextmon;
33
34 for (mon = mlist; mon != NULL; mon = nextmon) {
35 tp = THINGPTR(mon);
36 nextmon = next(mon);
37 if (off(*tp, ISHELD) && on(*tp, ISRUN)) {
38 if (tp->t_nomove > 0)
39 if (--tp->t_nomove > 0)
40 continue;
41 if (on(*tp, ISHASTE))
42 if (do_chase(mon) == -1)
43 continue;
44 if (off(*tp, ISSLOW) || tp->t_turn)
45 if (do_chase(mon) == -1)
46 continue;
47 tp->t_turn ^= TRUE;
48 }
49 }
50 }
51
52
53 /*
54 * do_chase:
55 * Make one thing chase another.
56 */
57 do_chase(mon)
58 struct linked_list *mon;
59 {
60 reg struct thing *th;
61 reg struct room *rer, *ree, *rxx;
62 reg int mindist, i, dist;
63 struct stats *st;
64 bool stoprun = FALSE, ondoor = FALSE, link = FALSE;
65 char runaway, dofight, wound, sch, ch;
66 struct coord this;
67 struct trap *trp;
68
69 th = THINGPTR(mon);
70 wound = th->t_flags & ISWOUND;
71 if (wound)
72 mindist = 0;
73 else
74 mindist = FARAWAY;
75 runaway = wound;
76 dofight = !runaway;
77 rer = th->t_room;
78 if (th->t_type == 'V') {
79 if (rer != NULL && !rf_on(rer, ISDARK)) {
80 /*
81 * Vampires can't stand the light
82 */
83 if (cansee(th->t_pos.y, th->t_pos.x))
84 msg("The vampire vaporizes into thin air !");
85 killed(mon, FALSE);
86 return(-1);
87 }
88 }
89 ree = roomin(th->t_dest); /* room of chasee */
90 this = *th->t_dest;
91 /*
92 * If the object of our desire is in a different
93 * room, then run to the door nearest to our goal.
94 */
95 if (mvinch(th->t_pos.y, th->t_pos.x) == DOOR)
96 ondoor = TRUE;
97 rxx = NULL;
98 if (rer != NULL || ree != NULL) {
99 /*
100 * Monster not in room, hero in room. Run to closest door
101 * in hero's room if not wounded. Run away if wounded.
102 */
103 if (rer == NULL && ree != NULL) {
104 if (!wound)
105 rxx = ree;
106 }
107 /*
108 * Monster in a room, hero not in room. If on a door,
109 * then use closest distance. If not on a door, then
110 * run to closest door in monsters room.
111 */
112 else if (rer != NULL && ree == NULL) {
113 if (!ondoor) {
114 rxx = rer;
115 if (wound)
116 runaway = FALSE;
117 }
118 }
119 /*
120 * Both hero and monster in a DIFFERENT room. Set flag to
121 * check for links between the monster's and hero's rooms.
122 * If no links are found, then the closest door in the
123 * monster's room is used.
124 */
125 else if (rer != ree) {
126 if (!wound) {
127 link = TRUE;
128 if (ondoor)
129 rxx = ree; /* if on door, run to heros room */
130 else
131 rxx = rer; /* else to nearest door this room */
132 }
133 }
134 /*
135 * Both hero and monster in same room. If monster is
136 * wounded, find the best door to run to.
137 */
138 else if (wound) {
139 struct coord *ex;
140 int poss, mdtd, hdtd, ghdtd, nx, gx = 0, best;
141
142 best = ghdtd = -FARAWAY;
143 for (nx = 0; nx < ree->r_nexits; nx++) {
144 ex = &ree->r_exit[nx];
145 if (mvinch(ex->y, ex->x) == SECRETDOOR)
146 continue;
147 gx += 1;
148 mdtd = abs(th->t_pos.y - ex->y) + abs(th->t_pos.x - ex->x);
149 hdtd = abs(hero.y - ex->y) + abs(hero.x - ex->x);
150 poss = hdtd - mdtd; /* possible move */
151 if (poss > best) {
152 best = poss;
153 this = *ex;
154 }
155 else if (poss == best && hdtd > ghdtd) {
156 ghdtd = hdtd;
157 best = poss;
158 this = *ex;
159 }
160 }
161 runaway = FALSE; /* go for target */
162 if (best < 1)
163 dofight = TRUE; /* fight if we must */
164 mdtd = (gx <= 1 && best < 1);
165 if (ondoor || mdtd) {
166 this = hero;
167 runaway = TRUE;
168 if (!mdtd)
169 dofight = FALSE;
170 }
171 }
172 if (rxx != NULL) {
173 for (i = 0; i < rxx->r_nexits; i += 1) {
174 dist = RDIST(th->t_dest, rxx->r_exit[i]);
175 if (link && rxx->r_ptr[i] == ree)
176 dist = -1;
177 if ((!wound && dist < mindist) ||