comparison arogue5/sticks.c @ 63:0ed67132cf10

Import Advanced Rogue 5.8 from the Roguelike Restoration Project (r1490)
author elwin
date Thu, 09 Aug 2012 22:58:48 +0000
parents
children c49f7927b0fa
comparison
equal deleted inserted replaced
62:0ef99244acb8 63:0ed67132cf10
1 /*
2 * Functions to implement the various sticks one might find
3 * while wandering around the dungeon.
4 *
5 * Advanced Rogue
6 * Copyright (C) 1984, 1985 Michael Morgan, Ken Dalka and AT&T
7 * All rights reserved.
8 *
9 * Based on "Rogue: Exploring the Dungeons of Doom"
10 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
11 * All rights reserved.
12 *
13 * See the file LICENSE.TXT for full copyright and licensing information.
14 */
15
16 #include "curses.h"
17 #include <ctype.h>
18 #include "rogue.h"
19
20
21 /*
22 * zap a stick and see what happens
23 */
24 do_zap(gotdir, which, flag)
25 bool gotdir;
26 int which;
27 int flag;
28 {
29 register struct linked_list *item;
30 register struct object *obj = NULL;
31 register struct thing *tp;
32 register int y, x;
33 struct linked_list *nitem;
34 struct object *nobj;
35 bool cursed, blessed, is_stick;
36
37 blessed = FALSE;
38 cursed = FALSE;
39 is_stick = FALSE;
40
41 if (which == 0) {
42 if ((item = get_item(pack, "zap with", ZAPPABLE)) == NULL)
43 return(FALSE);
44 obj = OBJPTR(item);
45
46 /* Handle relics specially here */
47 if (obj->o_type == RELIC) {
48 switch (obj->o_which) {
49 case ORCUS_WAND:
50 msg(nothing);
51 return(TRUE);
52 when MING_STAFF:
53 which = WS_MISSILE;
54 when ASMO_ROD:
55 switch (rnd(3)) {
56 case 0:
57 which = WS_ELECT;
58 when 1:
59 which = WS_COLD;
60 otherwise:
61 which = WS_FIRE;
62 }
63 }
64 cursed = FALSE;
65 blessed = FALSE;
66 }
67 else {
68 which = obj->o_which;
69 ws_know[which] = TRUE;
70 cursed = (obj->o_flags & ISCURSED) != 0;
71 blessed = (obj->o_flags & ISBLESSED) != 0;
72 is_stick = TRUE;
73 }
74 }
75 else {
76 cursed = flag & ISCURSED;
77 blessed = flag & ISBLESSED;
78 }
79 switch (which) { /* no direction for these */
80 case WS_LIGHT:
81 case WS_DRAIN:
82 case WS_CHARGE:
83 case WS_CURING:
84 break;
85
86 default:
87 if (!get_dir())
88 return(FALSE);
89 if (!gotdir) {
90 do {
91 delta.y = rnd(3) - 1;
92 delta.x = rnd(3) - 1;
93 } while (delta.y == 0 && delta.x == 0);
94 }
95 }
96
97 if (is_stick) {
98 if (obj->o_charges < 1) {
99 msg(nothing);
100 return(TRUE);
101 }
102 obj->o_charges--;
103 }
104 if (which == WS_WONDER) {
105 switch (rnd(14)) {
106 case 0: which = WS_ELECT;
107 when 1: which = WS_FIRE;
108 when 2: which = WS_COLD;
109 when 3: which = WS_POLYMORPH;
110 when 4: which = WS_MISSILE;
111 when 5: which = WS_SLOW_M;
112 when 6: which = WS_TELMON;
113 when 7: which = WS_CANCEL;
114 when 8: which = WS_CONFMON;
115 when 9: which = WS_DISINTEGRATE;
116 when 10: which = WS_PETRIFY;
117 when 11: which = WS_PARALYZE;
118 when 12: which = WS_MDEG;
119 when 13: which = WS_FEAR;
120 }
121 if(ws_magic[which].mi_curse>0 && rnd(100)<=ws_magic[which].mi_curse){
122 cursed = TRUE;
123 blessed = FALSE;
124 }
125 }
126
127 switch (which) {
128 case WS_LIGHT:
129 /*
130 * Reddy Kilowat wand. Light up the room
131 */
132 blue_light(blessed, cursed);
133 when WS_DRAIN:
134 /*
135 * Take away 1/2 of hero's hit points, then take it away
136 * evenly from the monsters in the room or next to hero
137 * if he is in a passage (but leave the monsters alone
138 * if the stick is cursed)
139 */
140 if (pstats.s_hpt < 2) {
141 msg("You are too weak to use it.");
142 return(TRUE);
143 }
144 if (cursed)
145 pstats.s_hpt /= 2;
146 else
147 drain(hero.y-1, hero.y+1, hero.x-1, hero.x+1);
148 when WS_POLYMORPH:
149 case WS_TELMON:
150 case WS_CANCEL:
151 {
152 register char monster, oldch;
153 register int rm;
154
155 y = hero.y;
156 x = hero.x;
157 while (shoot_ok(winat(y, x))) {
158 y += delta.y;
159 x += delta.x;
160 }
161 if (isalpha(monster = CCHAR( mvwinch(mw, y, x) ))) {
162 register struct room *rp;
163
164 item = find_mons(y, x);
165 tp = THINGPTR(item);
166 /* if the monster gets the saving throw, leave the case */
167 if (save(VS_MAGIC, tp, 0)) {
168 msg(nothing);
169 break;
170 }
171
172 /* Unhold player */
173 if (on(*tp, DIDHOLD)) {
174 turn_off(*tp, DIDHOLD);
175 if (--hold_count == 0) turn_off(player, ISHELD);
176 }
177 /* unsuffocate player */
178 if (on(*tp, DIDSUFFOCATE)) {
179 turn_off(*tp, DIDSUFFOCATE);
180 extinguish(suffocate);
181 }
182 rp = roomin(&tp->t_pos);
183 /*
184 * check to see if room should go dark
185 */
186 if (on(*tp, HASFIRE)) {
187 if (rp != NULL) {
188 register struct linked_list *fire_item;
189
190 for (fire_item = rp->r_fires; fire_item != NULL;
191 fire_item = next(fire_item)) {
192 if (THINGPTR(fire_item) == tp) {
193 detach(rp->r_fires, fire_item);
194 destroy_item(fire_item);
195 if (rp->r_fires == NULL) {
196 rp->r_flags &= ~HASFIRE;
197 if(cansee(tp->t_pos.y,tp->t_pos.x))
198 light(&hero);
199 }
200 break;
201 }
202 }
203 }
204 }
205
206 if (which == WS_POLYMORPH) {
207 register struct linked_list *pitem;
208
209 delta.x = x;
210 delta.y = y;
211 detach(mlist, item);
212 oldch = tp->t_oldch;
213 pitem = tp->t_pack; /* save his pack */
214 tp->t_pack = NULL;
215 new_monster(item,rnd(NUMMONST-NUMUNIQUE-1)+1,&delta,FALSE);
216 if (tp->t_pack != NULL)
217 o_free_list (tp->t_pack);
218 tp->t_pack = pitem;
219 monster = tp->t_type;
220 if (isalpha(mvwinch(cw, y, x)))
221 mvwaddch(cw, y, x, monster);
222 tp->t_oldch = oldch;
223 /*
224 * should the room light up?
225 */
226 if (on(*tp, HASFIRE)) {
227 if (rp) {
228 register struct linked_list *fire_item;
229
230 fire_item = creat_item();
231 ldata(fire_item) = (char *) tp;
232 attach(rp->r_fires, fire_item);
233 rp->r_flags |= HASFIRE;
234 if (cansee(tp->t_pos.y,tp->t_pos.x) &&
235 next(rp->r_fires) == NULL) light(&hero);
236 }
237 }
238 msg(terse ? "A new %s!" : "You have created a new %s!",
239 monsters[tp->t_index].m_name);
240 }
241 else if (which == WS_CANCEL) {
242 tp->t_flags[0] &= CANC0MASK;
243 tp->t_flags[1] &= CANC1MASK;
244 tp->t_flags[2] &= CANC2MASK;
245 tp->t_flags[3] &= CANC3MASK;
246 tp->t_flags[4] &= CANC4MASK;
247 tp->t_flags[4] &= CANC5MASK;
248 }
249 else { /* A teleport stick */
250 if (cursed) { /* Teleport monster to player */
251 if ((y == (hero.y + delta.y)) &&
252 (x == (hero.x + delta.x)))
253 msg(nothing);
254 else {
255 tp->t_pos.y = hero.y + delta.y;
256 tp->t_pos.x = hero.x + delta.x;
257 }
258 }
259 else if (blessed) { /* Get rid of monster */
260 killed(item, FALSE, TRUE);
261 return(TRUE);
262 }
263 else {
264 register int i=0;
265
266 do { /* Move monster to another room */
267 rm = rnd_room();
268 rnd_pos(&rooms[rm], &tp->t_pos);
269 }until(winat(tp->t_pos.y,tp->t_pos.x)==FLOOR ||i++>500);
270 rp = &rooms[rm];
271 }
272
273 /* Now move the monster */
274 if (isalpha(mvwinch(cw, y, x)))
275 mvwaddch(cw, y, x, tp->t_oldch);
276 turn_off(*tp, ISDISGUISE);
277 mvwaddch(mw, y, x, ' ');
278 mvwaddch(mw, tp->t_pos.y, tp->t_pos.x, monster);
279 if (tp->t_pos.y != y || tp->t_pos.x != x)
280 tp->t_oldch = CCHAR( mvwinch(cw, tp->t_pos.y, tp->t_pos.x) );
281 /*
282 * check to see if room that creature appears in should
283 * light up
284 */
285 if (on(*tp, HASFIRE)) {
286 register struct linked_list *fire_item;
287
288 fire_item = creat_item();
289 ldata(fire_item) = (char *) tp;
290 attach(rp->r_fires, fire_item);
291 rp->r_flags |= HASFIRE;
292 if(cansee(tp->t_pos.y, tp->t_pos.x) &&
293 next(rp->r_fires) == NULL)
294 light(&hero);
295 }
296 }
297 runto(tp, &hero);
298 }
299 }
300 when WS_MISSILE:
301 {
302 static struct object bolt =
303 {
304 MISSILE , {0, 0}, "", 0, "", "1d4 " , NULL, 0, WS_MISSILE, 50, 1
305 };
306
307 sprintf(bolt.o_hurldmg, "%dd4", pstats.s_lvl);
308 do_motion(&bolt, delta.y, delta.x, &player);
309 if (!hit_monster(unc(bolt.o_pos), &bolt, &player))
310 msg("The missile vanishes with a puff of smoke");
311 }
312 when WS_HIT:
313 {
314 register char ch;
315 struct object strike; /* don't want to change sticks attributes */
316
317 delta.y += hero.y;
318 delta.x += hero.x;
319 ch = CCHAR( winat(delta.y, delta.x) );
320 if (isalpha(ch))
321 {
322 strike = *obj;
323 strike.o_hplus = 6;
324 if (EQUAL(ws_type[which], "staff"))
325 strcpy(strike.o_damage,"3d8");
326 else
327 strcpy(strike.o_damage,"2d8");
328 fight(&delta, &strike, FALSE);
329 }
330 }
331 case WS_SLOW_M:
332 y = hero.y;
333 x = hero.x;
334 while (shoot_ok(winat(y, x))) {
335 y += delta.y;
336 x += delta.x;
337 }
338 if (isalpha(mvwinch(mw, y, x))) {
339 item = find_mons(y, x);
340 tp = THINGPTR(item);
341 runto(tp, &hero);
342 if (on(*tp, ISUNIQUE) && save(VS_MAGIC, tp, 0))
343 msg(nothing);
344 else if (on(*tp, NOSLOW))
345 msg(nothing);
346 else if (cursed) {
347 if (on(*tp, ISSLOW))
348 turn_off(*tp, ISSLOW);
349 else
350 turn_on(*tp, ISHASTE);
351 }
352 else if (blessed) {
353 turn_off(*tp, ISRUN);
354 turn_on(*tp, ISHELD);
355 return(TRUE);
356 }
357 else {
358 if (on(*tp, ISHASTE))
359 turn_off(*tp, ISHASTE);
360 else
361 turn_on(*tp, ISSLOW);
362 tp->t_turn = TRUE;
363 }
364 }
365 when WS_CHARGE:
366 if (ws_know[WS_CHARGE] != TRUE && is_stick)
367 msg("This is a wand of charging.");
368 if ((nitem = get_item(pack, "charge", STICK)) != NULL) {
369 nobj = OBJPTR(nitem);
370 if ((++(nobj->o_charges) == 1) && (nobj->o_which == WS_HIT))
371 fix_stick(nobj);
372 if (EQUAL(ws_type[nobj->o_which], "staff")) {
373 if (nobj->o_charges > 100)
374 nobj->o_charges = 100;
375 }
376 else {