Mercurial > hg > early-roguelike
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) || | |
