comparison srogue/rings.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 3aa87373c908
comparison
equal deleted inserted replaced
35:05018c63a721 36:2128c7dc8a40
1 /*
2 * routines dealing specifically with rings
3 *
4 * @(#)rings.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 /*
21 * ring_on:
22 * Put on a ring
23 */
24 ring_on()
25 {
26 reg struct object *obj;
27 reg struct linked_list *item;
28 reg int ring, wh;
29 char buf[LINLEN];
30 bool okring;
31
32 if (cur_ring[LEFT] != NULL && cur_ring[RIGHT] != NULL) {
33 msg("Already wearing two rings.");
34 after = FALSE;
35 return;
36 }
37 /*
38 * Make certain that it is somethings that we want to wear
39 */
40 if ((item = get_item("put on", RING)) == NULL)
41 return;
42 obj = OBJPTR(item);
43 if (obj->o_type != RING) {
44 msg("That won't fit on your finger.");
45 return;
46 }
47 /*
48 * find out which hand to put it on
49 */
50 if (is_current(obj))
51 return;
52 if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) {
53 if ((ring = gethand(FALSE)) < 0)
54 return;
55 }
56 else if (cur_ring[LEFT] == NULL)
57 ring = LEFT;
58 else
59 ring = RIGHT;
60 cur_ring[ring] = obj;
61 wh = obj->o_which;
62 /*
63 * okring = FALSE when:
64 * 1) ring is cursed and benefit = plus
65 * 2) ring is blessed and benefit = minus
66 */
67 okring = !((obj->o_ac > 0 && o_on(obj, ISCURSED)) ||
68 (obj->o_ac < 0 && o_on(obj, ISBLESS)));
69 /*
70 * Calculate the effect it has on the poor guy (if possible).
71 */
72 if (okring) {
73 switch (wh) {
74 case R_SPEED:
75 if (--obj->o_ac < 0) {
76 obj->o_ac = 0;
77 setoflg(obj,ISCURSED);
78 }
79 else {
80 add_haste(FALSE);
81 msg("You find yourself moving must faster.");
82 }
83 when R_GIANT: /* to 24 */
84 him->s_ef.a_str = MAXSTR;
85 when R_ADDSTR:
86 chg_abil(STR,obj->o_ac,FROMRING);
87 when R_KNOW:
88 chg_abil(WIS,obj->o_ac,FROMRING);
89 when R_DEX:
90 chg_abil(DEX,obj->o_ac,FROMRING);
91 when R_CONST:
92 chg_abil(CON,obj->o_ac,FROMRING);
93 when R_SEEINVIS:
94 player.t_flags |= CANSEE;
95 light(&hero);
96 mvwaddch(cw, hero.y, hero.x, PLAYER);
97 when R_AGGR:
98 aggravate();
99 when R_HEAVY:
100 updpack(); /* new pack weight */
101 when R_BLIND:
102 r_know[R_BLIND] = TRUE;
103 player.t_flags |= ISBLIND;
104 look(FALSE);
105 when R_SLOW:
106 player.t_flags |= ISSLOW;
107 when R_SAPEM:
108 fuse(sapem,TRUE,150);
109 when R_LIGHT: {
110 struct room *rop;
111
112 r_know[R_LIGHT] = TRUE;
113 if ((rop = player.t_room) != NULL) {
114 rop->r_flags &= ~ISDARK;
115 light(&hero);
116 mvwaddch(cw, hero.y, hero.x, PLAYER);
117 }
118 }
119 }
120 }
121 if (r_know[wh] && r_guess[wh]) {
122 free(r_guess[wh]);
123 r_guess[wh] = NULL;
124 }
125 else if(!r_know[wh] && r_guess[wh] == NULL) {
126 mpos = 0;
127 strcpy(buf, r_stones[wh]);
128 msg(callit);
129 if (get_str(buf, cw) == NORM) {
130 r_guess[wh] = new(strlen(buf) + 1);
131 strcpy(r_guess[wh], buf);
132 }
133 }
134 mpos = 0;
135 msg("Now wearing %s",inv_name(obj,TRUE));
136 ringfood = ring_eat();
137 nochange = FALSE;
138 }
139
140
141 /*
142 * ring_off:
143 * Take off some ring
144 */
145 ring_off()
146 {
147 reg int ring;
148 reg struct object *obj;
149
150 if (cur_ring[LEFT] == NULL && cur_ring[RIGHT] == NULL) {
151 msg("You're not wearing any rings.");
152 return;
153 }
154 else if (cur_ring[LEFT] == NULL)
155 ring = RIGHT;
156 else if (cur_ring[RIGHT] == NULL)
157 ring = LEFT;
158 else
159 if ((ring = gethand(TRUE)) < 0)
160 return;
161 mpos = 0;
162 obj = cur_ring[ring];
163 if (obj == NULL) {
164 msg("Not wearing such a ring.");
165 return;
166 }
167 if (dropcheck(obj)) {
168 msg("Was wearing %s", inv_name(obj, TRUE));
169 nochange = FALSE;
170 ringfood = ring_eat();
171 }
172 }
173
174
175 /*
176 * toss_ring:
177 * Remove a ring and stop its effects
178 */
179 toss_ring(what)
180 struct object *what;
181 {
182 bool okring;
183
184 /*
185 * okring = FALSE when:
186 * 1) ring is cursed and benefit = plus
187 * 2) ring is blessed and benefit = minus
188 */
189 okring = !((what->o_ac > 0 && o_on(what, ISCURSED)) ||
190 (what->o_ac < 0 && o_on(what, ISBLESS)));
191
192 cur_ring[what == cur_ring[LEFT] ? LEFT : RIGHT] = NULL;
193 if (okring) {
194 switch (what->o_which) {
195 case R_SPEED:
196 extinguish(nohaste);
197 nohaste(FALSE);
198 when R_BLIND:
199 sight(FALSE);
200 when R_SLOW:
201 player.t_flags &= ~ISSLOW;
202 when R_SAPEM:
203 extinguish(sapem);
204 when R_GIANT:
205 him->s_ef = him->s_re;
206 ringabil();
207 when R_ADDSTR:
208 chg_abil(STR,-what->o_ac,FALSE);
209 when R_KNOW:
210 chg_abil(WIS,-what->o_ac,FALSE);
211 when R_DEX:
212 chg_abil(DEX,-what->o_ac,FALSE);
213 when R_CONST:
214 chg_abil(CON,-what->o_ac,FALSE);
215 when R_SEEINVIS:
216 player.t_flags &= ~CANSEE;
217 extinguish(unsee);
218 light(&hero);
219 mvwaddch(cw, hero.y, hero.x, PLAYER);
220 }
221 }
222 }
223
224
225 /*
226 * gethand:
227 * Get a hand to wear a ring
228 */
229 gethand(isrmv)
230 bool isrmv;
231 {
232 reg int c;
233 char *ptr;
234 struct object *obj;
235
236 while(1) {
237 addmsg("Left or Right ring");
238 if (isrmv)
239 addmsg(starlist);
240 addmsg("? ");
241 endmsg();
242 c = readchar();
243 if (isupper(c))
244 c = tolower(c);
245 if (c == '*' && isrmv) {
246 wclear(hw);
247 obj = cur_ring[LEFT];
248 if (obj != NULL)
249 ptr = inv_name(obj, TRUE);
250 else
251 ptr = "none";
252 wprintw(hw, "L) %s\n\r",ptr);
253 obj = cur_ring[RIGHT];
254 if (obj != NULL)
255 ptr = inv_name(obj, TRUE);
256 else
257 ptr = "none";
258 wprintw(hw, "R) %s\n\r", ptr);
259 wprintw(hw, "\n\r\nWhich hand? ");
260 draw(hw);
261 c = readchar();
262 if (isupper(c))
263 c = tolower(c);
264 restscr(cw);
265 }
266 if (c == 'l')
267 return LEFT;
268 else if (c == 'r')
269 return RIGHT;
270 else if (c == ESCAPE)
271 return -1;
272 mpos = 0;
273 msg("L or R");
274 }
275 }
276
277 /*
278 * ring_eat:
279 * How much food do the hero's rings use up?
280 */
281 ring_eat()
282 {
283 reg struct object *lb;
284 reg int hand, i, howmuch;
285 bool addit;
286
287 howmuch = 0;
288 addit = TRUE;
289 for (i = LEFT; i <= RIGHT ; i += 1) {
290 lb = cur_ring[i];
291 if (lb != NULL) {
292 switch (lb->o_which) {
293 case R_REGEN:
294 case R_GIANT:
295 howmuch += 2;
296 when R_SPEED:
297 case R_SUSTSTR:
298 case R_SUSAB:
299 howmuch += 1;
300 when R_SEARCH:
301 howmuch += (rnd(100) < 33);
302 when R_DIGEST:
303 switch(lb->o_ac) {
304 case -3: if (rnd(100) < 25)
305 howmuch += 3;
306 when -2: if (rnd(100) < 50)
307 howmuch += 2;
308 when -1: howmuch += 1;
309 when 0: howmuch -= (rnd(100) < 50);
310 when 3: if (rnd(100) < 25)
311 howmuch -= 3;
312 when 2: if (rnd(100) < 50)
313 howmuch -= 2;
314 default: howmuch -= 1;
315 }
316 otherwise:
317 addit = FALSE;
318 }
319 if (addit) {
320 if (o_on(lb, ISBLESS))
321 howmuch -= 1;
322 else if (o_on(lb, ISCURSED))
323 howmuch += 1;
324 }
325 }
326 }
327 return howmuch;
328 }
329
330
331 /*
332 * ring_num:
333 * Print ring bonuses
334 */
335 char *
336 ring_num(what)
337 struct object *what;
338 {
339 static char number[5];
340
341 number[0] = '\0';
342 if (o_on(what,ISKNOW) || o_on(what,ISPOST)) {
343 if (magring(what)) { /* only rings with numbers */
344 number[0] = ' ';
345 strcpy(&number[1], num(what->o_ac, 0));
346 }
347 }
348 return number;
349 }
350
351
352 /*
353 * magring:
354 * Returns TRUE if a ring has a number, i.e. +2
355 */
356 magring(what)
357 struct object *what;
358 {
359 switch(what->o_which) {
360 case R_SPEED:
361 case R_ADDSTR:
362 case R_PROTECT:
363 case R_ADDHIT:
364 case R_ADDDAM:
365 case R_DIGEST:
366 case R_CONST:
367 case R_KNOW:
368 case R_DEX:
369 return TRUE;
370 default:
371 return FALSE;
372 }
373 }
374
375
376 /*
377 * ringabil:
378 * Compute effective abilities due to rings
379 */
380 ringabil()
381 {
382 reg struct object *rptr;
383 reg int i;
384
385 for(i = LEFT; i <= RIGHT; i++) {
386 rptr = cur_ring[i];
387 if (rptr != NULL) {
388 switch(rptr->o_which) {
389 case R_ADDSTR:
390 chg_abil(STR,rptr->o_ac,FROMRING);
391 when R_DEX:
392 chg_abil(DEX,rptr->o_ac,FROMRING);
393 when R_KNOW:
394 chg_abil(WIS,rptr->o_ac,FROMRING);
395 when R_CONST:
396 chg_abil(CON,rptr->o_ac,FROMRING);
397 }
398 }
399 }
400 }
401
402
403 /*
404 * init_ring:
405 * Initialize a ring
406 */
407 init_ring(what,fromwiz)
408 struct object *what;
409 bool fromwiz; /* TRUE when from wizards */
410 {
411 reg int much;
412
413 switch (what->o_which) {
414 case R_DIGEST: /* -3 to +3 rings */
415 case R_ADDSTR:
416 case R_PROTECT:
417 case R_ADDHIT:
418 case R_ADDDAM:
419 case R_DEX:
420 case R_KNOW:
421 case R_CONST:
422 if (fromwiz) {
423 much = getbless(); /* get wizards response */
424 }
425 else { /* normal users */
426 if (rnd(100) < 25)
427 much = -rnd(3) - 1;
428 else
429 much = rnd(3) + 1;
430 }
431 what->o_ac = much;
432 if (much < 0)
433 setoflg(what,ISCURSED);
434 when R_SPEED:
435 what->o_ac = rnd(4) + 1;
436 when R_AGGR:
437 case R_DELUS:
438 case R_HEAVY:
439 case R_BLIND:
440 case R_SLOW:
441 case R_SAPEM:
442 case R_TELEPORT:
443 what->o_ac = 0;
444 setoflg(what,ISCURSED);
445 when R_GIANT:
446 what->o_ac = 25; /* lots !! of STR */
447 otherwise:
448 what->o_ac = 1;
449 }
450 what->o_type = RING;
451 what->o_weight = things[TYP_RING].mi_wght;
452 what->o_typname = things[TYP_RING].mi_name;
453 what->o_vol = itemvol(what);
454 }
455
456 /*
457 * ringex:
458 * Get extra gains from rings
459 */
460 ringex(rtype)
461 int rtype;
462 {
463 reg int howmuch = 0;
464
465 if (isring(LEFT, rtype))
466 howmuch += cur_ring[LEFT]->o_ac;
467 if (isring(RIGHT, rtype))
468 howmuch += cur_ring[RIGHT]->o_ac;
469 return howmuch;
470 }
471
472 /*
473 * iswearing:
474 * Returns TRUE when the hero is wearing a certain type of ring
475 */
476 iswearing(ring)
477 int ring;
478 {
479 return (isring(LEFT,ring) || isring(RIGHT,ring));
480 }
481
482 /*
483 * isring:
484 * Returns TRUE if a ring is on a hand
485 */
486 isring(hand,ring)
487 int hand, ring;
488 {
489 if (cur_ring[hand] != NULL && cur_ring[hand]->o_which == ring)
490 return TRUE;
491 return FALSE;
492 }