comparison rogue3/things.c @ 0:527e2150eaf0

Import Rogue 3.6 from the Roguelike Restoration Project (r1490)
author edwarj4
date Tue, 13 Oct 2009 13:33:34 +0000
parents
children 0250220d8cdd
comparison
equal deleted inserted replaced
-1:000000000000 0:527e2150eaf0
1 /*
2 * Contains functions for dealing with things like
3 * potions and scrolls
4 *
5 * @(#)things.c 3.37 (Berkeley) 6/15/81
6 *
7 * Rogue: Exploring the Dungeons of Doom
8 * Copyright (C) 1980, 1981 Michael Toy, Ken Arnold and Glenn Wichman
9 * All rights reserved.
10 *
11 * See the file LICENSE.TXT for full copyright and licensing information.
12 */
13
14 #include "curses.h"
15 #include <ctype.h>
16 #include <string.h>
17 #include "rogue.h"
18
19 /*
20 * inv_name:
21 * return the name of something as it would appear in an
22 * inventory.
23 */
24 char *
25 inv_name(struct object *obj, int drop)
26 {
27 char *pb;
28
29 switch(obj->o_type)
30 {
31 case SCROLL:
32 if (obj->o_count == 1)
33 strcpy(prbuf, "A scroll ");
34 else
35 sprintf(prbuf, "%d scrolls ", obj->o_count);
36 pb = &prbuf[strlen(prbuf)];
37 if (s_know[obj->o_which])
38 sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
39 else if (s_guess[obj->o_which])
40 sprintf(pb, "called %s", s_guess[obj->o_which]);
41 else
42 sprintf(pb, "titled '%s'", s_names[obj->o_which]);
43 when POTION:
44 if (obj->o_count == 1)
45 strcpy(prbuf, "A potion ");
46 else
47 sprintf(prbuf, "%d potions ", obj->o_count);
48 pb = &prbuf[strlen(prbuf)];
49 if (p_know[obj->o_which])
50 sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
51 p_colors[obj->o_which]);
52 else if (p_guess[obj->o_which])
53 sprintf(pb, "called %s(%s)", p_guess[obj->o_which],
54 p_colors[obj->o_which]);
55 else if (obj->o_count == 1)
56 sprintf(prbuf, "A%s %s potion",
57 vowelstr(p_colors[obj->o_which]),
58 p_colors[obj->o_which]);
59 else
60 sprintf(prbuf, "%d %s potions", obj->o_count,
61 p_colors[obj->o_which]);
62 when FOOD:
63 if (obj->o_which == 1)
64 if (obj->o_count == 1)
65 sprintf(prbuf, "A%s %s", vowelstr(fruit), fruit);
66 else
67 sprintf(prbuf, "%d %ss", obj->o_count, fruit);
68 else
69 if (obj->o_count == 1)
70 strcpy(prbuf, "Some food");
71 else
72 sprintf(prbuf, "%d rations of food", obj->o_count);
73 when WEAPON:
74 if (obj->o_count > 1)
75 sprintf(prbuf, "%d ", obj->o_count);
76 else
77 strcpy(prbuf, "A ");
78 pb = &prbuf[strlen(prbuf)];
79 if (obj->o_flags & ISKNOW)
80 sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus),
81 w_names[obj->o_which]);
82 else
83 sprintf(pb, "%s", w_names[obj->o_which]);
84 if (obj->o_count > 1)
85 strcat(prbuf, "s");
86 when ARMOR:
87 if (obj->o_flags & ISKNOW)
88 sprintf(prbuf, "%s %s",
89 num(a_class[obj->o_which] - obj->o_ac, 0),
90 a_names[obj->o_which]);
91 else
92 sprintf(prbuf, "%s", a_names[obj->o_which]);
93 when AMULET:
94 strcpy(prbuf, "The Amulet of Yendor");
95 when STICK:
96 sprintf(prbuf, "A %s ", ws_type[obj->o_which]);
97 pb = &prbuf[strlen(prbuf)];
98 if (ws_know[obj->o_which])
99 sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
100 charge_str(obj), ws_made[obj->o_which]);
101 else if (ws_guess[obj->o_which])
102 sprintf(pb, "called %s(%s)", ws_guess[obj->o_which],
103 ws_made[obj->o_which]);
104 else
105 sprintf(&prbuf[2], "%s %s", ws_made[obj->o_which],
106 ws_type[obj->o_which]);
107 when RING:
108 if (r_know[obj->o_which])
109 sprintf(prbuf, "A%s ring of %s(%s)", ring_num(obj),
110 r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
111 else if (r_guess[obj->o_which])
112 sprintf(prbuf, "A ring called %s(%s)",
113 r_guess[obj->o_which], r_stones[obj->o_which]);
114 else
115 sprintf(prbuf, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
116 r_stones[obj->o_which]);
117 otherwise:
118 debug("Picked up something funny");
119 sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type));
120 }
121 if (obj == cur_armor)
122 strcat(prbuf, " (being worn)");
123 if (obj == cur_weapon)
124 strcat(prbuf, " (weapon in hand)");
125 if (obj == cur_ring[LEFT])
126 strcat(prbuf, " (on left hand)");
127 else if (obj == cur_ring[RIGHT])
128 strcat(prbuf, " (on right hand)");
129 if (drop && isupper(prbuf[0]))
130 prbuf[0] = tolower(prbuf[0]);
131 else if (!drop && islower(*prbuf))
132 *prbuf = toupper(*prbuf);
133 if (!drop)
134 strcat(prbuf, ".");
135 return prbuf;
136 }
137
138 /*
139 * money:
140 * Add to characters purse
141 */
142 void
143 money()
144 {
145 struct room *rp;
146
147 for (rp = rooms; rp <= &rooms[MAXROOMS-1]; rp++)
148 if (ce(hero, rp->r_gold))
149 {
150 if (notify)
151 {
152 if (!terse)
153 addmsg("You found ");
154 msg("%d gold pieces.", rp->r_goldval);
155 }
156 purse += rp->r_goldval;
157 rp->r_goldval = 0;
158 cmov(rp->r_gold);
159 addch(FLOOR);
160 return;
161 }
162 msg("That gold must have been counterfeit");
163 }
164
165 /*
166 * drop:
167 * put something down
168 */
169 void
170 drop()
171 {
172 int ch;
173 struct linked_list *obj, *nobj;
174 struct object *op;
175
176 ch = mvwinch(stdscr, hero.y, hero.x);
177 if (ch != FLOOR && ch != PASSAGE)
178 {
179 msg("There is something there already");
180 return;
181 }
182 if ((obj = get_item("drop", 0)) == NULL)
183 return;
184 op = (struct object *) ldata(obj);
185 if (!dropcheck(op))
186 return;
187 /*
188 * Take it out of the pack
189 */
190 if (op->o_count >= 2 && op->o_type != WEAPON)
191 {
192 nobj = new_item(sizeof *op);
193 op->o_count--;
194 op = (struct object *) ldata(nobj);
195 *op = *((struct object *) ldata(obj));
196 op->o_count = 1;
197 obj = nobj;
198 if (op->o_group != 0)
199 inpack++;
200 }
201 else
202 detach(pack, obj);
203 inpack--;
204 /*
205 * Link it into the level object list
206 */
207 attach(lvl_obj, obj);
208 mvaddch(hero.y, hero.x, op->o_type);
209 op->o_pos = hero;
210 msg("Dropped %s", inv_name(op, TRUE));
211 }
212
213 /*
214 * do special checks for dropping or unweilding|unwearing|unringing
215 */
216 int
217 dropcheck(struct object *op)
218 {
219 str_t save_max;
220
221 if (op == NULL)
222 return TRUE;
223 if (op != cur_armor && op != cur_weapon
224 && op != cur_ring[LEFT] && op != cur_ring[RIGHT])
225 return TRUE;
226 if (op->o_flags & ISCURSED)
227 {
228 msg("You can't. It appears to be cursed.");
229 return FALSE;
230 }
231 if (op == cur_weapon)
232 cur_weapon = NULL;
233 else if (op == cur_armor)
234 {
235 waste_time();
236 cur_armor = NULL;
237 }
238 else if (op == cur_ring[LEFT] || op == cur_ring[RIGHT])
239 {
240 switch (op->o_which)
241 {
242 case R_ADDSTR:
243 save_max = max_stats.s_str;
244 chg_str(-op->o_ac);
245 max_stats.s_str = save_max;
246 break;
247 case R_SEEINVIS:
248 player.t_flags &= ~CANSEE;
249 extinguish(unsee);
250 light(&hero);
251 mvwaddch(cw, hero.y, hero.x, PLAYER);
252 break;
253 }
254 cur_ring[op == cur_ring[LEFT] ? LEFT : RIGHT] = NULL;
255 }
256 return TRUE;
257 }
258
259 /*
260 * return a new thing
261 */
262 struct linked_list *
263 new_thing()
264 {
265 struct linked_list *item;
266 struct object *cur;
267 int j, k;
268
269 item = new_item(sizeof *cur);
270 cur = (struct object *) ldata(item);
271 cur->o_hplus = cur->o_dplus = 0;
272 strcpy(cur->o_damage,"0d0");
273 strcpy(cur->o_hurldmg,"0d0");
274 cur->o_ac = 11;
275 cur->o_count = 1;
276 cur->o_group = 0;
277 cur->o_flags = 0;
278 /*
279 * Decide what kind of object it will be
280 * If we haven't had food for a while, let it be food.
281 */
282 switch (no_food > 3 ? 2 : pick_one(things, NUMTHINGS))
283 {
284 case 0:
285 cur->o_type = POTION;
286 cur->o_which = pick_one(p_magic, MAXPOTIONS);
287 when 1:
288 cur->o_type = SCROLL;
289 cur->o_which = pick_one(s_magic, MAXSCROLLS);
290 when 2:
291 no_food = 0;
292 cur->o_type = FOOD;
293 if (rnd(100) > 10)
294 cur->o_which = 0;
295 else
296 cur->o_which = 1;
297 when 3:
298 cur->o_type = WEAPON;
299 cur->o_which = rnd(MAXWEAPONS);
300 init_weapon(cur, cur->o_which);
301 if ((k = rnd(100)) < 10)
302 {
303 cur->o_flags |= ISCURSED;
304 cur->o_hplus -= rnd(3)+1;
305 }
306 else if (k < 15)
307 cur->o_hplus += rnd(3)+1;
308 when 4:
309 cur->o_type = ARMOR;
310 for (j = 0, k = rnd(100); j < MAXARMORS; j++)
311 if (k < a_chances[j])
312 break;
313 if (j == MAXARMORS)
314 {
315 debug("Picked a bad armor %d", k);
316 j = 0;
317 }
318 cur->o_which = j;
319 cur->o_ac = a_class[j];
320 if ((k = rnd(100)) < 20)
321 {
322 cur->o_flags |= ISCURSED;
323 cur->o_ac += rnd(3)+1;
324 }
325 else if (k < 28)
326 cur->o_ac -= rnd(3)+1;
327 when 5:
328 cur->o_type = RING;
329 cur->o_which = pick_one(r_magic, MAXRINGS);
330 switch (cur->o_which)
331 {
332 case R_ADDSTR:
333 case R_PROTECT:
334 case R_ADDHIT:
335 case R_ADDDAM:
336 if ((cur->o_ac = rnd(3)) == 0)
337 {
338 cur->o_ac = -1;
339 cur->o_flags |= ISCURSED;
340 }
341 when R_AGGR:
342 case R_TELEPORT:
343 cur->o_flags |= ISCURSED;
344 }
345 when 6:
346 cur->o_type = STICK;
347 cur->o_which = pick_one(ws_magic, MAXSTICKS);
348 fix_stick(cur);
349 otherwise:
350 debug("Picked a bad kind of object");
351 wait_for(stdscr, ' ');
352 }
353 return item;
354 }
355
356 /*
357 * pick an item out of a list of nitems possible magic items
358 */
359 int
360 pick_one(struct magic_item *magic, int nitems)
361 {
362 struct magic_item *end;
363 int i;
364 struct magic_item *start;
365
366 start = magic;
367 for (end = &magic[nitems], i = rnd(100); magic < end; magic++)
368 if (i < magic->mi_prob)
369 break;
370 if (magic == end)
371 {
372 if (wizard)
373 {
374 msg("bad pick_one: %d from %d items", i, nitems);
375 for (magic = start; magic < end; magic++)
376 msg("%s: %d%%", magic->mi_name, magic->mi_prob);
377 }
378 magic = start;
379 }
380 return (int) (magic - start);
381 }