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