comparison xrogue/sticks.c @ 133:e6179860cb76

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