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);