Add f)lirt command. All it does right now is shoot a tilde.
[rogue-pphs.git] / things.c
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(obj, drop)
26 register struct object *obj;
27 register bool drop;
28 {
29 register char *pb;
30
31 switch(obj->o_type)
32 {
33 case SCROLL:
34 if (obj->o_count == 1)
35 strcpy(prbuf, "A scroll ");
36 else
37 sprintf(prbuf, "%d scrolls ", obj->o_count);
38 pb = &prbuf[strlen(prbuf)];
39 if (s_know[obj->o_which])
40 sprintf(pb, "of %s", s_magic[obj->o_which].mi_name);
41 else if (s_guess[obj->o_which])
42 sprintf(pb, "called %s", s_guess[obj->o_which]);
43 else
44 sprintf(pb, "titled '%s'", s_names[obj->o_which]);
45 when POTION:
46 if (obj->o_count == 1)
47 strcpy(prbuf, "A potion ");
48 else
49 sprintf(prbuf, "%d potions ", obj->o_count);
50 pb = &prbuf[strlen(prbuf)];
51 if (p_know[obj->o_which])
52 sprintf(pb, "of %s(%s)", p_magic[obj->o_which].mi_name,
53 p_colors[obj->o_which]);
54 else if (p_guess[obj->o_which])
55 sprintf(pb, "called %s(%s)", p_guess[obj->o_which],
56 p_colors[obj->o_which]);
57 else if (obj->o_count == 1)
58 sprintf(prbuf, "A%s %s potion",
59 vowelstr(p_colors[obj->o_which]),
60 p_colors[obj->o_which]);
61 else
62 sprintf(prbuf, "%d %s potions", obj->o_count,
63 p_colors[obj->o_which]);
64 when FOOD:
65 if (obj->o_which == 1)
66 if (obj->o_count == 1)
67 sprintf(prbuf, "A%s %s", vowelstr(fruit), fruit);
68 else
69 sprintf(prbuf, "%d %ss", obj->o_count, fruit);
70 else
71 if (obj->o_count == 1)
72 strcpy(prbuf, "Some food");
73 else
74 sprintf(prbuf, "%d rations of food", obj->o_count);
75 when WEAPON:
76 if (obj->o_count > 1)
77 sprintf(prbuf, "%d ", obj->o_count);
78 else
79 strcpy(prbuf, "A ");
80 pb = &prbuf[strlen(prbuf)];
81 if (obj->o_flags & ISKNOW)
82 sprintf(pb, "%s %s", num(obj->o_hplus, obj->o_dplus),
83 w_names[obj->o_which]);
84 else
85 sprintf(pb, "%s", w_names[obj->o_which]);
86 if (obj->o_count > 1)
87 strcat(prbuf, "s");
88 when ARMOR:
89 if (obj->o_flags & ISKNOW)
90 sprintf(prbuf, "%s %s",
91 num(a_class[obj->o_which] - obj->o_ac, 0),
92 a_names[obj->o_which]);
93 else
94 sprintf(prbuf, "%s", a_names[obj->o_which]);
95 when AMULET:
96 strcpy(prbuf, "The Amulet of Yendor");
97 when STICK:
98 sprintf(prbuf, "A %s ", ws_type[obj->o_which]);
99 pb = &prbuf[strlen(prbuf)];
100 if (ws_know[obj->o_which])
101 sprintf(pb, "of %s%s(%s)", ws_magic[obj->o_which].mi_name,
102 charge_str(obj), ws_made[obj->o_which]);
103 else if (ws_guess[obj->o_which])
104 sprintf(pb, "called %s(%s)", ws_guess[obj->o_which],
105 ws_made[obj->o_which]);
106 else
107 sprintf(&prbuf[2], "%s %s", ws_made[obj->o_which],
108 ws_type[obj->o_which]);
109 when RING:
110 if (r_know[obj->o_which])
111 sprintf(prbuf, "A%s ring of %s(%s)", ring_num(obj),
112 r_magic[obj->o_which].mi_name, r_stones[obj->o_which]);
113 else if (r_guess[obj->o_which])
114 sprintf(prbuf, "A ring called %s(%s)",
115 r_guess[obj->o_which], r_stones[obj->o_which]);
116 else
117 sprintf(prbuf, "A%s %s ring", vowelstr(r_stones[obj->o_which]),
118 r_stones[obj->o_which]);
119 otherwise:
120 debug("Picked up something funny");
121 sprintf(prbuf, "Something bizarre %s", unctrl(obj->o_type));
122 }
123 if (obj == cur_armor)
124 strcat(prbuf, " (being worn)");
125 if (obj == cur_weapon)
126 strcat(prbuf, " (weapon in hand)");
127 if (obj == cur_ring[LEFT])
128 strcat(prbuf, " (on left hand)");
129 else if (obj == cur_ring[RIGHT])
130 strcat(prbuf, " (on right hand)");
131 if (drop && isupper(prbuf[0]))
132 prbuf[0] = tolower(prbuf[0]);
133 else if (!drop && islower(*prbuf))
134 *prbuf = toupper(*prbuf);
135 if (!drop)
136 strcat(prbuf, ".");
137 return prbuf;
138 }
139
140 /*
141 * money:
142 * Add to characters purse
143 */
144 money()
145 {
146 register struct room *rp;
147
148 for (rp = rooms; rp <= &rooms[MAXROOMS-1]; rp++)
149 if (ce(hero, rp->r_gold))
150 {
151 if (notify)
152 {
153 if (!terse)
154 addmsg("You found ");
155 msg("%d gold pieces.", rp->r_goldval);
156 }
157 purse += rp->r_goldval;
158 rp->r_goldval = 0;
159 cmov(rp->r_gold);
160 addch(FLOOR);
161 return;
162 }
163 msg("That gold must have been counterfeit");
164 }
165
166 /*
167 * drop:
168 * put something down
169 */
170 drop()
171 {
172 register char ch;
173 register struct linked_list *obj, *nobj;
174 register 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 dropcheck(op)
217 register 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 register struct linked_list *item;
266 register struct object *cur;
267 register 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(' ');
352 }
353 return item;
354 }
355
356 /*
357 * pick an item out of a list of nitems possible magic items
358 */
359 pick_one(magic, nitems)
360 register struct magic_item *magic;
361 int nitems;
362 {
363 register struct magic_item *end;
364 register int i;
365 register struct magic_item *start;
366
367 start = magic;
368 for (end = &magic[nitems], i = rnd(100); magic < end; magic++)
369 if (i < magic->mi_prob)
370 break;
371 if (magic == end)
372 {
373 if (wizard)
374 {
375 msg("bad pick_one: %d from %d items", i, nitems);
376 for (magic = start; magic < end; magic++)
377 msg("%s: %d%%", magic->mi_name, magic->mi_prob);
378 }
379 magic = start;
380 }
381 return magic - start;
382 }