date and time created 88/07/22 16:08:01 by bostic
[unix-history] / usr / src / games / rogue / use.c
CommitLineData
b3afadef
KB
1/*
2 * use.c
3 *
4 * This source herein may be modified and/or distributed by anybody who
5 * so desires, with the following restrictions:
6 * 1.) No portion of this notice shall be removed.
7 * 2.) Credit shall not be taken for the creation of this source.
8 * 3.) This code is not to be traded, sold, or used for personal
9 * gain or profit.
10 *
11 */
12
13#ifndef lint
14static char sccsid[] = "@(#)use.c 5.1 (Berkeley) %G%";
15#endif /* not lint */
16
17#include "rogue.h"
18
19short halluc = 0;
20short blind = 0;
21short confused = 0;
22short levitate = 0;
23short haste_self = 0;
24boolean see_invisible = 0;
25short extra_hp = 0;
26boolean detect_monster = 0;
27boolean con_mon = 0;
28char *strange_feeling = "you have a strange feeling for a moment, then it passes";
29
30extern short bear_trap;
31extern char hunger_str[];
32extern short cur_room;
33extern long level_points[];
34extern boolean being_held;
35extern char *fruit, *you_can_move_again;
36extern boolean sustain_strength;
37
38quaff()
39{
40 short ch;
41 char buf[80];
42 object *obj;
43
44 ch = pack_letter("quaff what?", POTION);
45
46 if (ch == CANCEL) {
47 return;
48 }
49 if (!(obj = get_letter_object(ch))) {
50 message("no such item.", 0);
51 return;
52 }
53 if (obj->what_is != POTION) {
54 message("you can't drink that", 0);
55 return;
56 }
57 switch(obj->which_kind) {
58 case INCREASE_STRENGTH:
59 message("you feel stronger now, what bulging muscles!",
60 0);
61 rogue.str_current++;
62 if (rogue.str_current > rogue.str_max) {
63 rogue.str_max = rogue.str_current;
64 }
65 break;
66 case RESTORE_STRENGTH:
67 rogue.str_current = rogue.str_max;
68 message("this tastes great, you feel warm all over", 0);
69 break;
70 case HEALING:
71 message("you begin to feel better", 0);
72 potion_heal(0);
73 break;
74 case EXTRA_HEALING:
75 message("you begin to feel much better", 0);
76 potion_heal(1);
77 break;
78 case POISON:
79 if (!sustain_strength) {
80 rogue.str_current -= get_rand(1, 3);
81 if (rogue.str_current < 1) {
82 rogue.str_current = 1;
83 }
84 }
85 message("you feel very sick now", 0);
86 if (halluc) {
87 unhallucinate();
88 }
89 break;
90 case RAISE_LEVEL:
91 rogue.exp_points = level_points[rogue.exp - 1];
92 message("you suddenly feel much more skillful", 0);
93 add_exp(1, 1);
94 break;
95 case BLINDNESS:
96 go_blind();
97 break;
98 case HALLUCINATION:
99 message("oh wow, everything seems so cosmic", 0);
100 halluc += get_rand(500, 800);
101 break;
102 case DETECT_MONSTER:
103 show_monsters();
104 if (!(level_monsters.next_monster)) {
105 message(strange_feeling, 0);
106 }
107 break;
108 case DETECT_OBJECTS:
109 if (level_objects.next_object) {
110 if (!blind) {
111 show_objects();
112 }
113 } else {
114 message(strange_feeling, 0);
115 }
116 break;
117 case CONFUSION:
118 message((halluc ? "what a trippy feeling" :
119 "you feel confused"), 0);
120 cnfs();
121 break;
122 case LEVITATION:
123 message("you start to float in the air", 0);
124 levitate += get_rand(15, 30);
125 being_held = bear_trap = 0;
126 break;
127 case HASTE_SELF:
128 message("you feel yourself moving much faster", 0);
129 haste_self += get_rand(11, 21);
130 if (!(haste_self % 2)) {
131 haste_self++;
132 }
133 break;
134 case SEE_INVISIBLE:
135 sprintf(buf, "hmm, this potion tastes like %sjuice", fruit);
136 message(buf, 0);
137 if (blind) {
138 unblind();
139 }
140 see_invisible = 1;
141 relight();
142 break;
143 }
144 print_stats((STAT_STRENGTH | STAT_HP));
145 if (id_potions[obj->which_kind].id_status != CALLED) {
146 id_potions[obj->which_kind].id_status = IDENTIFIED;
147 }
148 vanish(obj, 1, &rogue.pack);
149}
150
151read_scroll()
152{
153 short ch;
154 object *obj;
155 char msg[DCOLS];
156
157 ch = pack_letter("read what?", SCROL);
158
159 if (ch == CANCEL) {
160 return;
161 }
162 if (!(obj = get_letter_object(ch))) {
163 message("no such item.", 0);
164 return;
165 }
166 if (obj->what_is != SCROL) {
167 message("you can't read that", 0);
168 return;
169 }
170 switch(obj->which_kind) {
171 case SCARE_MONSTER:
172 message("you hear a maniacal laughter in the distance",
173 0);
174 break;
175 case HOLD_MONSTER:
176 hold_monster();
177 break;
178 case ENCH_WEAPON:
179 if (rogue.weapon) {
180 if (rogue.weapon->what_is == WEAPON) {
181 sprintf(msg, "your %sglow%s %sfor a moment",
182 name_of(rogue.weapon),
183 ((rogue.weapon->quantity <= 1) ? "s" : ""),
184 get_ench_color());
185 message(msg, 0);
186 if (coin_toss()) {
187 rogue.weapon->hit_enchant++;
188 } else {
189 rogue.weapon->d_enchant++;
190 }
191 }
192 rogue.weapon->is_cursed = 0;
193 } else {
194 message("your hands tingle", 0);
195 }
196 break;
197 case ENCH_ARMOR:
198 if (rogue.armor) {
199 sprintf(msg, "your armor glows %sfor a moment",
200 get_ench_color());
201 message(msg, 0);
202 rogue.armor->d_enchant++;
203 rogue.armor->is_cursed = 0;
204 print_stats(STAT_ARMOR);
205 } else {
206 message("your skin crawls", 0);
207 }
208 break;
209 case IDENTIFY:
210 message("this is a scroll of identify", 0);
211 obj->identified = 1;
212 id_scrolls[obj->which_kind].id_status = IDENTIFIED;
213 idntfy();
214 break;
215 case TELEPORT:
216 tele();
217 break;
218 case SLEEP:
219 message("you fall asleep", 0);
220 take_a_nap();
221 break;
222 case PROTECT_ARMOR:
223 if (rogue.armor) {
224 message( "your armor is covered by a shimmering gold shield",0);
225 rogue.armor->is_protected = 1;
226 rogue.armor->is_cursed = 0;
227 } else {
228 message("your acne seems to have disappeared", 0);
229 }
230 break;
231 case REMOVE_CURSE:
232 message((!halluc) ?
233 "you feel as though someone is watching over you" :
234 "you feel in touch with the universal oneness", 0);
235 uncurse_all();
236 break;
237 case CREATE_MONSTER:
238 create_monster();
239 break;
240 case AGGRAVATE_MONSTER:
241 aggravate();
242 break;
243 case MAGIC_MAPPING:
244 message("this scroll seems to have a map on it", 0);
245 draw_magic_map();
246 break;
247 case CON_MON:
248 con_mon = 1;
249 sprintf(msg, "your hands glow %sfor a moment", get_ench_color());
250 message(msg, 0);
251 break;
252 }
253 if (id_scrolls[obj->which_kind].id_status != CALLED) {
254 id_scrolls[obj->which_kind].id_status = IDENTIFIED;
255 }
256 vanish(obj, (obj->which_kind != SLEEP), &rogue.pack);
257}
258
259/* vanish() does NOT handle a quiver of weapons with more than one
260 * arrow (or whatever) in the quiver. It will only decrement the count.
261 */
262
263vanish(obj, rm, pack)
264object *obj;
265short rm;
266object *pack;
267{
268 if (obj->quantity > 1) {
269 obj->quantity--;
270 } else {
271 if (obj->in_use_flags & BEING_WIELDED) {
272 unwield(obj);
273 } else if (obj->in_use_flags & BEING_WORN) {
274 unwear(obj);
275 } else if (obj->in_use_flags & ON_EITHER_HAND) {
276 un_put_on(obj);
277 }
278 take_from_pack(obj, pack);
279 free_object(obj);
280 }
281 if (rm) {
282 (void) reg_move();
283 }
284}
285
286potion_heal(extra)
287{
288 float ratio;
289 short add;
290
291 rogue.hp_current += rogue.exp;
292
293 ratio = ((float)rogue.hp_current) / rogue.hp_max;
294
295 if (ratio >= 1.00) {
296 rogue.hp_max += (extra ? 2 : 1);
297 extra_hp += (extra ? 2 : 1);
298 rogue.hp_current = rogue.hp_max;
299 } else if (ratio >= 0.90) {
300 rogue.hp_max += (extra ? 1 : 0);
301 extra_hp += (extra ? 1 : 0);
302 rogue.hp_current = rogue.hp_max;
303 } else {
304 if (ratio < 0.33) {
305 ratio = 0.33;
306 }
307 if (extra) {
308 ratio += ratio;
309 }
310 add = (short)(ratio * ((float)rogue.hp_max - rogue.hp_current));
311 rogue.hp_current += add;
312 if (rogue.hp_current > rogue.hp_max) {
313 rogue.hp_current = rogue.hp_max;
314 }
315 }
316 if (blind) {
317 unblind();
318 }
319 if (confused && extra) {
320 unconfuse();
321 } else if (confused) {
322 confused = (confused / 2) + 1;
323 }
324 if (halluc && extra) {
325 unhallucinate();
326 } else if (halluc) {
327 halluc = (halluc / 2) + 1;
328 }
329}
330
331idntfy()
332{
333 short ch;
334 object *obj;
335 struct id *id_table;
336 char desc[DCOLS];
337AGAIN:
338 ch = pack_letter("what would you like to identify?", ALL_OBJECTS);
339
340 if (ch == CANCEL) {
341 return;
342 }
343 if (!(obj = get_letter_object(ch))) {
344 message("no such item, try again", 0);
345 message("", 0);
346 check_message();
347 goto AGAIN;
348 }
349 obj->identified = 1;
350 if (obj->what_is & (SCROL | POTION | WEAPON | ARMOR | WAND | RING)) {
351 id_table = get_id_table(obj);
352 id_table[obj->which_kind].id_status = IDENTIFIED;
353 }
354 get_desc(obj, desc);
355 message(desc, 0);
356}
357
358eat()
359{
360 short ch;
361 short moves;
362 object *obj;
363 char buf[70];
364
365 ch = pack_letter("eat what?", FOOD);
366
367 if (ch == CANCEL) {
368 return;
369 }
370 if (!(obj = get_letter_object(ch))) {
371 message("no such item.", 0);
372 return;
373 }
374 if (obj->what_is != FOOD) {
375 message("you can't eat that", 0);
376 return;
377 }
378 if ((obj->which_kind == FRUIT) || rand_percent(60)) {
379 moves = get_rand(950, 1150);
380 if (obj->which_kind == RATION) {
381 message("yum, that tasted good", 0);
382 } else {
383 sprintf(buf, "my, that was a yummy %s", fruit);
384 message(buf, 0);
385 }
386 } else {
387 moves = get_rand(750, 950);
388 message("yuk, that food tasted awful", 0);
389 add_exp(2, 1);
390 }
391 rogue.moves_left /= 3;
392 rogue.moves_left += moves;
393 hunger_str[0] = 0;
394 print_stats(STAT_HUNGER);
395
396 vanish(obj, 1, &rogue.pack);
397}
398
399hold_monster()
400{
401 short i, j;
402 short mcount = 0;
403 object *monster;
404 short row, col;
405
406 for (i = -2; i <= 2; i++) {
407 for (j = -2; j <= 2; j++) {
408 row = rogue.row + i;
409 col = rogue.col + j;
410 if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) ||
411 (col > (DCOLS-1))) {
412 continue;
413 }
414 if (dungeon[row][col] & MONSTER) {
415 monster = object_at(&level_monsters, row, col);
416 monster->m_flags |= ASLEEP;
417 monster->m_flags &= (~WAKENS);
418 mcount++;
419 }
420 }
421 }
422 if (mcount == 0) {
423 message("you feel a strange sense of loss", 0);
424 } else if (mcount == 1) {
425 message("the monster freezes", 0);
426 } else {
427 message("the monsters around you freeze", 0);
428 }
429}
430
431tele()
432{
433 mvaddch(rogue.row, rogue.col, get_dungeon_char(rogue.row, rogue.col));
434
435 if (cur_room >= 0) {
436 darken_room(cur_room);
437 }
438 put_player(get_room_number(rogue.row, rogue.col));
439 being_held = 0;
440 bear_trap = 0;
441}
442
443hallucinate()
444{
445 object *obj, *monster;
446 short ch;
447
448 if (blind) return;
449
450 obj = level_objects.next_object;
451
452 while (obj) {
453 ch = mvinch(obj->row, obj->col);
454 if (((ch < 'A') || (ch > 'Z')) &&
455 ((obj->row != rogue.row) || (obj->col != rogue.col)))
456 if ((ch != ' ') && (ch != '.') && (ch != '#') && (ch != '+')) {
457 addch(gr_obj_char());
458 }
459 obj = obj->next_object;
460 }
461 monster = level_monsters.next_monster;
462
463 while (monster) {
464 ch = mvinch(monster->row, monster->col);
465 if ((ch >= 'A') && (ch <= 'Z')) {
466 addch(get_rand('A', 'Z'));
467 }
468 monster = monster->next_monster;
469 }
470}
471
472unhallucinate()
473{
474 halluc = 0;
475 relight();
476 message("everything looks SO boring now", 1);
477}
478
479unblind()
480{
481 blind = 0;
482 message("the veil of darkness lifts", 1);
483 relight();
484 if (halluc) {
485 hallucinate();
486 }
487 if (detect_monster) {
488 show_monsters();
489 }
490}
491
492relight()
493{
494 if (cur_room == PASSAGE) {
495 light_passage(rogue.row, rogue.col);
496 } else {
497 light_up_room(cur_room);
498 }
499 mvaddch(rogue.row, rogue.col, rogue.fchar);
500}
501
502take_a_nap()
503{
504 short i;
505
506 i = get_rand(2, 5);
507 md_sleep(1);
508
509 while (i--) {
510 mv_mons();
511 }
512 md_sleep(1);
513 message(you_can_move_again, 0);
514}
515
516go_blind()
517{
518 short i, j;
519
520 if (!blind) {
521 message("a cloak of darkness falls around you", 0);
522 }
523 blind += get_rand(500, 800);
524
525 if (detect_monster) {
526 object *monster;
527
528 monster = level_monsters.next_monster;
529
530 while (monster) {
531 mvaddch(monster->row, monster->col, monster->trail_char);
532 monster = monster->next_monster;
533 }
534 }
535 if (cur_room >= 0) {
536 for (i = rooms[cur_room].top_row + 1;
537 i < rooms[cur_room].bottom_row; i++) {
538 for (j = rooms[cur_room].left_col + 1;
539 j < rooms[cur_room].right_col; j++) {
540 mvaddch(i, j, ' ');
541 }
542 }
543 }
544 mvaddch(rogue.row, rogue.col, rogue.fchar);
545}
546
547char *
548get_ench_color()
549{
550 if (halluc) {
551 return(id_potions[get_rand(0, POTIONS-1)].title);
552 } else if (con_mon) {
553 return("red ");
554 }
555 return("blue ");
556}
557
558cnfs()
559{
560 confused += get_rand(12, 22);
561}
562
563unconfuse()
564{
565 char msg[80];
566
567 confused = 0;
568 sprintf(msg, "you feel less %s now", (halluc ? "trippy" : "confused"));
569 message(msg, 1);
570}
571
572uncurse_all()
573{
574 object *obj;
575
576 obj = rogue.pack.next_object;
577
578 while (obj) {
579 obj->is_cursed = 0;
580 obj = obj->next_object;
581 }
582}