Mercurial > hg > early-roguelike
comparison xrogue/effects.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 effects.c - functions for dealing with appllying effects to monsters | |
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 "rogue.h" | |
21 | |
22 /* | |
23 * effect: | |
24 * Check for effects of one thing hitting another thing. Return | |
25 * the reason code if the defender is killed. Otherwise return 0. | |
26 */ | |
27 | |
28 effect(att, def, weap, thrown, see_att, see_def) | |
29 register struct thing *att, *def; | |
30 struct object *weap; | |
31 bool thrown; | |
32 register bool see_att, see_def; | |
33 { | |
34 register bool att_player, def_player; | |
35 char attname[LINELEN+1], defname[LINELEN+1]; | |
36 | |
37 /* See if the attacker or defender is the player */ | |
38 att_player = (att == &player); | |
39 def_player = (def == &player); | |
40 | |
41 /* | |
42 * If the player could see the attacker or defender, they can't | |
43 * surprise anymore (don't bother checking if they could). | |
44 */ | |
45 if (see_att) turn_off(*att, CANSURPRISE); | |
46 if (see_def) turn_off(*def, CANSURPRISE); | |
47 | |
48 /* What are the attacker and defender names? */ | |
49 if (att_player) strcpy(attname, "you"); | |
50 else { | |
51 if (see_att) strcpy(attname, monster_name(att)); | |
52 else strcpy(attname, "something"); | |
53 } | |
54 | |
55 if (def_player) strcpy(defname, "you"); | |
56 else { | |
57 if (see_def) strcpy(defname, monster_name(def)); | |
58 else strcpy(defname, "something"); | |
59 } | |
60 | |
61 /* | |
62 * See what happens to the attacker first. We can skip this | |
63 * whole section, however, if the defender is the player. | |
64 * Nothing happens (yet) to anyone just for hitting the player. | |
65 */ | |
66 if (!def_player) { | |
67 if (!thrown) { /* Some things require a direct hit. */ | |
68 /* | |
69 * If the attacker hits a rusting monster, The weapon | |
70 * may be damaged | |
71 */ | |
72 if (on(*def, CANRUST) && weap && | |
73 weap->o_type != RELIC && (weap->o_flags & ISMETAL) && | |
74 !(weap->o_flags & ISPROT)) { | |
75 if ((weap->o_hplus < 1 && weap->o_dplus < 1) || | |
76 roll(1,20) < weap->o_hplus+weap->o_dplus+10) { | |
77 if (rnd(100) < 50) weap->o_hplus--; | |
78 else weap->o_dplus--; | |
79 if (att_player) | |
80 msg(terse ? "Your %s weakens!" | |
81 : "Your %s gets weaker!", | |
82 weaps[weap->o_which].w_name); | |
83 } | |
84 } | |
85 } | |
86 | |
87 /* If the attacker hit something that shrieks, wake the dungeon */ | |
88 if (on(*def, CANSHRIEK)) { | |
89 if (see_def) | |
90 msg("%s emits an ear piercing shriek! ", prname(defname, TRUE)); | |
91 else | |
92 msg("You hear an ear piercing shriek!"); | |
93 | |
94 /* Friendly charactors should be immune */ | |
95 if (player.t_ctype == C_PALADIN || | |
96 player.t_ctype == C_RANGER || player.t_ctype == C_MONK) | |
97 aggravate(TRUE, FALSE); | |
98 else | |
99 aggravate(TRUE, TRUE); | |
100 } | |
101 | |
102 /* | |
103 * does the creature explode when hit? | |
104 */ | |
105 if (on(*def, CANEXPLODE)) { | |
106 if (see_def) msg("%s explodes!", prname(defname, TRUE)); | |
107 else msg("You hear a tremendous explosion!"); | |
108 explode(def); | |
109 if (pstats.s_hpt < 1) { | |
110 pstats.s_hpt = -1; | |
111 death(def->t_index); | |
112 } | |
113 } | |
114 } | |
115 | |
116 /* | |
117 * Now let's see what happens to the defender. Start out with | |
118 * the things that everyone can do. Then exit if the attacker | |
119 * is the player. | |
120 */ | |
121 if (!thrown) { | |
122 /* | |
123 * Can the player confuse? | |
124 */ | |
125 if (on(*att, CANHUH) && att_player) { | |
126 msg("Your hands return to normal. "); | |
127 if (off(*def, ISCLEAR) && | |
128 (off(*def, ISUNIQUE) || !save(VS_MAGIC, def, 0))) { | |
129 if (see_def) msg("%s appears confused!", prname(defname, TRUE)); | |
130 turn_on(*def, ISHUH); | |
131 } | |
132 turn_off(*att, CANHUH); | |
133 } | |
134 | |
135 /* Return now if the attacker is the player. */ | |
136 if (att_player) return(0); | |
137 | |
138 /* | |
139 * Some monsters may take half your hit points | |
140 */ | |
141 if (on(*att, CANSUCK) && !save(VS_MAGIC, def, 0)) { | |
142 if (def->t_stats.s_hpt == 1) return(att->t_index); /* Killed! */ | |
143 else { | |
144 def->t_stats.s_hpt /= 2; | |
145 if (def_player) | |
146 msg("Your life force is being drained out of you."); | |
147 } | |
148 } | |
149 | |
150 /* | |
151 * If a hugging monster hits, it may SQUEEEEEEEZE. | |
152 */ | |
153 if (on(*att, CANHUG)) { | |
154 if (roll(1,20) >= 18 || roll(1,20) >= 18) { | |
155 if (def_player) | |
156 msg("%s squeezes itself nastily against you!", | |
157 prname(attname, TRUE)); | |
158 else if (see_att) | |
159 msg("%s squeezes real hard!", prname(attname, TRUE)); | |
160 | |
161 if ((def->t_stats.s_hpt -= roll(2,8)) <= 0) | |
162 return(att->t_index); | |
163 } | |
164 } | |
165 | |
166 /* | |
167 * Some monsters have poisonous bites. | |
168 */ | |
169 if (on(*att, CANPOISON) && !save(VS_POISON, def, 0)) { | |
170 if (def_player) { | |
171 if (ISWEARING(R_SUSABILITY)) | |
172 msg(terse ? "Sting has no effect." | |
173 : "A sting momentarily weakens your arm."); | |
174 else { | |
175 chg_str(-1); | |
176 msg(terse ? "A sting has weakened you." : | |
177 "You get stung in the arm! You feel weaker. "); | |
178 } | |
179 } | |
180 else { | |
181 /* Subtract a strength point and see if it kills it */ | |
182 if (--def->t_stats.s_str <= 0) return(D_STRENGTH); | |
183 } | |
184 } | |
185 | |
186 /* | |
187 * Turning to stone: | |
188 */ | |
189 if (on(*att, TOUCHSTONE)) { | |
190 if (def_player) turn_off(*att, TOUCHSTONE); | |
191 if (on(*def, CANINWALL)) { | |
192 if (def_player) | |
193 msg("%s's touch has no effect.", prname(attname, TRUE)); | |
194 } | |
195 else { | |
196 if (!save(VS_PETRIFICATION, def, 0) && rnd(100) < 10) { | |
197 if (def_player) { | |
198 msg("Your body begins to solidify.. "); | |
199 msg("You are transformed into stone!! --More--"); | |
200 wait_for(' '); | |
201 return(D_PETRIFY); | |
202 } | |
203 else { | |
204 /* The monster got stoned! */ | |
205 turn_on(*def, ISSTONE); | |
206 turn_off(*def, ISRUN); | |
207 turn_off(*def, ISINVIS); | |
208 turn_off(*def, ISDISGUISE); | |
209 if (def->t_stats.s_intel > 15) | |
210 msg("%s staggers.. ", prname(defname, TRUE)); | |
211 else if (see_def) | |
212 msg("%s turns to stone! ", prname(defname, TRUE)); | |
213 else if (cansee(unc(def->t_pos))) | |
214 msg("A statue appears out of nowhere! "); | |
215 } | |
216 } | |
217 else if (def->t_action != A_FREEZE) { | |
218 if (def_player) | |
219 msg("%s's touch stiffens your limbs.", | |
220 prname(attname, TRUE)); | |
221 else if (see_def) | |
222 msg("%s appears to freeze over.", prname(defname, TRUE)); | |
223 | |
224 def->t_no_move += movement(def) * STONETIME; | |
225 def->t_action = A_FREEZE; | |
226 } | |
227 } | |
228 } | |
229 | |
230 /* | |
231 * Wraiths might drain energy levels | |
232 */ | |
233 if ((on(*att, CANDRAIN) || on(*att, DOUBLEDRAIN)) && | |
234 !save(VS_POISON, def, 3-(att->t_stats.s_lvl/5))) { | |
235 if (def_player) { | |
236 lower_level(att->t_index); | |
237 if (on(*att, DOUBLEDRAIN)) lower_level(att->t_index); | |
238 turn_on(*att, DIDDRAIN); | |
239 } | |
240 else { | |
241 def->t_stats.s_hpt -= roll(1, 8); | |
242 def->t_stats.s_lvl--; | |
243 if (on(*att, DOUBLEDRAIN)) { | |
244 def->t_stats.s_hpt -= roll(1, 8); | |
245 def->t_stats.s_lvl--; | |
246 } | |
247 if (see_def) | |
248 msg("%s appears less skillful.", prname(defname, TRUE)); | |
249 | |
250 /* Did it kill it? */ | |
251 if (def->t_stats.s_hpt <= 0 || | |
252 def->t_stats.s_lvl <= 0) | |
253 return(att->t_index); | |
254 } | |
255 } | |
256 | |
257 /* | |
258 * Paralyzation: | |
259 */ | |
260 if (on(*att, CANPARALYZE) && def->t_action != A_FREEZE) { | |
261 if (def_player) turn_off(*att, CANPARALYZE); | |
262 if (!save(VS_PARALYZATION, def, 0)) { | |
263 if (on(*def, CANINWALL)) { | |
264 if (def_player) | |
265 msg("%s's touch has no effect.", prname(attname, TRUE)); | |
266 } | |
267 else { | |
268 if (def_player) | |
269 msg("%s's touch paralyzes you.", prname(attname, TRUE)); | |
270 else if (see_def) | |
271 msg("%s appears to freeze over!", prname(defname, TRUE)); | |
272 | |
273 def->t_no_move += movement(def) * FREEZETIME; | |
274 def->t_action = A_FREEZE; | |
275 } | |
276 } | |
277 } | |
278 | |
279 /* | |
280 * Painful wounds make the defendant faint | |
281 */ | |
282 if (on(*att, CANPAIN) && def->t_action != A_FREEZE) { | |
283 if (def_player) turn_off(*att, CANPAIN); | |
284 if (!ISWEARING(R_ALERT) && !save(VS_POISON, def, 0)) { | |
285 if (def_player) | |
286 msg("You faint from the painful wound!"); | |
287 else if (see_def) | |
288 msg("%s appears to faint!", prname(defname, TRUE)); | |
289 | |
290 def->t_no_move += movement(def) * PAINTIME; | |
291 def->t_action = A_FREEZE; | |
292 } | |
293 } | |
294 | |
295 /* | |
296 * Some things currently affect only the player. Let's make | |
297 * a check here so we don't have to check for each thing. | |
298 */ | |
299 if (def_player) { | |
300 /* | |
301 * Stinking monsters make the defender weaker (to hit). For now | |
302 * this will only affect the player. We may later add the HASSTINK | |
303 * effect to monsters, too. | |
304 */ | |
305 if (on(*att, CANSTINK)) { | |
306 turn_off(*att, CANSTINK); | |
307 if (!save(VS_POISON, def, 0)) { | |
308 msg("The stench of %s sickens you. Blech!", | |
309 prname(attname, FALSE)); | |
310 if (on(player, HASSTINK)) lengthen(unstink, STINKTIME); | |
311 else { | |
312 turn_on(player, HASSTINK); | |
313 fuse(unstink, (VOID *)NULL, STINKTIME, AFTER); | |
314 } | |
315 } | |
316 } | |
317 | |
318 /* | |
319 * Chilling monster reduces strength each time. This only | |
320 * affects the player for now because of its temporary nature. | |
321 */ | |
322 if (on(*att, CANCHILL)) { | |
323 if (!ISWEARING(R_SUSABILITY) && !save(VS_POISON, def, 0)) { | |
324 msg("You cringe at %s's chilling touch.", | |
325 prname(attname, FALSE)); | |
326 chg_str(-1); | |
327 if (lost_str++ == 0) | |
328 fuse(res_strength, (VOID *)NULL, CHILLTIME, AFTER); | |
329 else lengthen(res_strength, CHILLTIME); | |
330 } | |
331 } | |
332 | |
333 /* | |
334 * Itching monsters reduce dexterity (temporarily). This only | |
335 * affects the player for now because of its temporary nature. | |
336 */ | |
337 if (on(*att, CANITCH) && !save(VS_POISON, def, 0)) { | |
338 msg("The claws of %s scratch you!", prname(attname, FALSE)); | |
339 if (ISWEARING(R_SUSABILITY)) { | |
340 msg("The scratch has no effect."); | |
341 } | |
342 else { | |
343 (*add_abil[A_DEXTERITY])(-1); | |
344 } | |
345 } | |
346 | |
347 /* | |
348 * If a disease-carrying monster hits, there is a chance the | |
349 * defender will catch the disease. This only applies to the | |
350 * player for now because of the temporary nature. Don't affect | |
351 * the Ranger or Paladin. | |
352 */ | |
353 if (on(*att, CANDISEASE) && | |
354 (rnd(def->t_stats.s_const) < att->t_stats.s_lvl) && | |
355 off(*def, HASDISEASE)) { | |
356 if (ISWEARING(R_HEALTH) || | |
357 player.t_ctype == C_PALADIN || | |
358 player.t_ctype == C_RANGER) { | |
359 msg("The wound heals quickly."); | |
360 } | |
361 else { | |
362 turn_on(*def, HASDISEASE); | |
363 fuse(cure_disease, (VOID *)NULL, roll(HEALTIME,SICKTIME), AFTER); | |
364 msg(terse ? "You have been diseased!" | |
365 : "You have contracted an annoying disease!"); | |
366 } | |
367 } | |
368 | |
369 /* | |
370 * If a rusting monster hits, you lose armor. This only applies to | |
371 * the player because monsters don't wear armor (for now). | |
372 */ | |
373 if (on(*att, CANRUST)) { | |
374 if (cur_armor != NULL && | |
375 cur_armor->o_which != LEATHER && | |
376 cur_armor->o_which != STUDDED_LEATHER && | |
377 cur_armor->o_which != PADDED_ARMOR && | |
378 !(cur_armor->o_flags & ISPROT) && | |
379 cur_armor->o_ac < def->t_stats.s_arm+1) { | |
380 msg(terse ? "Your armor weakens." | |
381 : "Your armor becomes weaker."); | |
382 cur_armor->o_ac++; | |
383 } | |
384 if (cur_misc[WEAR_BRACERS] != NULL && | |
385 cur_misc[WEAR_BRACERS]->o_ac > 0 && | |
386 !(cur_misc[WEAR_BRACERS]->o_flags & ISPROT)) { | |
387 cur_misc[WEAR_BRACERS]->o_ac--; | |
388 if (cur_misc[WEAR_BRACERS]->o_ac == 0) { | |
389 register struct linked_list *item; | |
390 | |
391 for (item=pack; item!=NULL; item=next(item)) { | |
392 if (OBJPTR(item) == cur_misc[WEAR_BRACERS]) { | |
393 detach(pack, item); | |
394 o_discard(item); | |
395 break; | |
396 } | |
397 } | |
398 msg ("Your bracers crumble apart!"); | |
399 cur_misc[WEAR_BRACERS] = NULL; | |
400 inpack--; | |
401 } | |
402 else { | |
403 msg("Your bracers weaken!"); | |
404 } | |
405 } | |
406 } | |
407 | |
408 /* | |
409 * If can dissolve and hero has leather type armor. This | |
410 * also only applies to the player for now because of the | |
411 * armor. | |
412 */ | |
413 if (on(*att, CANDISSOLVE) && cur_armor != NULL && | |
414 (cur_armor->o_which == LEATHER || | |
415 cur_armor->o_which == STUDDED_LEATHER || | |
416 cur_armor->o_which == PADDED_ARMOR) && | |
417 !(cur_armor->o_flags & ISPROT) && | |
418 cur_armor->o_ac < def->t_stats.s_arm+1) { | |
419 msg(terse ? "Your armor dissolves!" | |
420 : "Your armor appears to have dissolved!"); | |
421 cur_armor->o_ac++; | |
422 } | |
423 | |
424 /* | |
425 * If an infesting monster hits you, you get a parasite or rot. | |
426 * This will only affect the player until we figure out how to | |
427 * make it affect monsters. Don't affect the Monk. | |
428 */ | |
429 if (on(*att, CANINFEST) && | |
430 rnd(def->t_stats.s_const) < att->t_stats.s_lvl) { | |
431 if (ISWEARING(R_HEALTH) || player.t_ctype == C_MONK) { | |
432 msg("The wound heals quickly."); | |
433 } | |
434 else { | |
435 turn_off(*att, CANINFEST); | |
436 msg(terse ? "You have been infested." | |
437 : "You have contracted a parasitic infestation!"); | |
438 infest_dam++; | |
439 turn_on(*def, HASINFEST); | |
440 } | |
441 } | |
442 | |
443 /* | |
444 * Does it take wisdom away? This currently affects only | |
445 * the player because of its temporary nature. | |
446 */ | |
447 if (on(*att, TAKEWISDOM) && | |
448 !save(VS_MAGIC, def, 0) && | |
449 !ISWEARING(R_SUSABILITY)) { | |
450 (*add_abil[A_WISDOM])(-1); | |
451 } | |
452 | |
453 /* | |
454 * Does it take intelligence away? This currently affects | |
455 * only the player because of its temporary nature. | |
456 */ | |
457 if (on(*att, TAKEINTEL) && | |
458 !save(VS_MAGIC, &player, 0) && | |
459 !ISWEARING(R_SUSABILITY)) { | |
460 (*add_abil[A_INTELLIGENCE])(-1); | |
461 } | |
462 | |
463 /* | |
464 * Cause fear by touching. This currently affects only | |
465 * the player until we figure out how we want it to | |
466 * affect monsters. | |
467 */ | |
468 if (on(*att, TOUCHFEAR)) { | |
469 turn_off(*att, TOUCHFEAR); | |
470 if (!ISWEARING(R_HEROISM) && | |
471 !save(VS_WAND, def, 0) && | |
472 !(on(*def, ISFLEE) && (def->t_dest == &att->t_pos))) { | |
473 turn_on(*def, ISFLEE); | |
474 def->t_dest = &att->t_pos; | |
475 msg("%s's touch terrifies you!", prname(attname, TRUE)); | |
476 | |
477 /* It is okay to turn tail */ | |
478 if (!def_player) def->t_oldpos = def->t_pos; | |
479 } | |
480 } | |
481 | |
482 /* | |
483 * Make the hero dance (as in otto's irresistable dance) | |
484 * This should be fairly easy to do to monsters, but | |
485 * we'll restrict it to players until we decide what to | |
486 * do about the temporary nature. | |
487 */ | |
488 if (on(*att, CANDANCE) && | |
489 !on(*def, ISDANCE) && | |
490 def->t_action != A_FREEZE && | |
491 !save(VS_MAGIC, def, -4)) { | |
492 turn_off(*att, CANDANCE); | |
493 turn_on(*def, ISDANCE); | |
494 msg("You begin to dance uncontrollably!"); | |
495 fuse(undance, (VOID *)NULL, roll(2,4), AFTER); | |
496 } | |
497 | |
498 /* | |
499 * Suffocating our hero. Monsters don't get suffocated. | |
500 * That's too hard for now. | |
501 */ | |
502 if (on(*att, CANSUFFOCATE) && | |
503 !ISWEARING(R_FREEDOM) && | |
504 rnd(100) < 30 && | |
505 (find_slot(suffocate) == 0)) { | |
506 turn_on(*att, DIDSUFFOCATE); | |
507 msg("%s is beginning to suffocate you!", prname(attname, TRUE)); | |
508 fuse(suffocate, (VOID *)NULL, roll(9,3), AFTER); | |
509 } | |
510 | |
511 /* | |
512 * some creatures stops the poor guy from moving. | |
513 * How can we do this to a monster? | |
514 */ | |
515 if (on(*att,CANHOLD) && off(*att,DIDHOLD) && !ISWEARING(R_FREEDOM)){ | |
516 turn_on(*def, ISHELD); | |
517 turn_on(*att, DIDHOLD); | |
518 hold_count++; | |
519 } | |
520 | |
521 /* | |
522 * Sucker will suck blood and run. This | |
523 * should be easy to have happen to a monster, | |
524 * but we have to decide how to handle the fleeing. | |
525 */ | |
526 if (on(*att, CANDRAW)) { | |
527 turn_off(*att, CANDRAW); | |
528 turn_on(*att, ISFLEE); | |
529 msg("%s sates itself with your blood!", prname(attname, TRUE)); | |
530 if ((def->t_stats.s_hpt -= 12) <= 0) return(att->t_index); | |
531 | |
532 /* It is okay to turn tail */ | |
533 att->t_oldpos = att->t_pos; | |
534 } | |
535 | |
536 /* | |
537 * Bad smell will force a reduction in strength. | |
538 * This will happen only to the player because of | |
539 * the temporary nature. | |
540 */ | |
541 if (on(*att, CANSMELL)) { | |
542 turn_off(*att, CANSMELL); | |
543 if (save(VS_MAGIC, def, 0) || ISWEARING(R_SUSABILITY)) { | |
544 if (terse) | |
545 msg("Pheww!"); | |
546 else | |
547 msg("You smell an unpleasant odor. Phew!"); | |
548 } | |
549 | |
550 else { | |
551 int odor_str = -(rnd(6)+1); | |
552 | |
553 msg("You are overcome by a foul odor!"); | |
554 if (lost_str == 0) { | |
555 chg_str(odor_str); | |
556 fuse(res_strength, (VOID *)NULL, SMELLTIME, AFTER); | |
557 lost_str -= odor_str; | |
558 } | |
559 else lengthen(res_strength, SMELLTIME); | |
560 } | |
561 } | |
562 | |
563 /* | |
564 * The monsters touch slows the defendant down. | |
565 */ | |
566 if (on(*att, TOUCHSLOW)) { | |
567 turn_off(*att, TOUCHSLOW); | |
568 if (!save(VS_PARALYZATION, def, 0)) | |
569 add_slow(); | |
570 } | |
571 | |
572 /* | |
573 * Rotting only affects the player. Don't affect the Monk, | |
574 * Paladin, or Ranger. | |
575 */ | |
576 if (on(*att, CANROT)) { | |
577 if (!ISWEARING(R_HEALTH) && | |
578 player.t_ctype != C_MONK && | |
579 player.t_ctype != C_RANGER && | |
580 player.t_ctype != C_PALADIN && | |
581 !save(VS_POISON, def, 0) && | |
582 off(*def, DOROT)) { | |
583 turn_on(*def, DOROT); | |
584 msg("You feel your skin starting to rot and peel away!"); | |
585 } | |
586 } | |
587 | |
588 /* | |
589 * Monsters should be able to steal gold from anyone, | |
590 * but until this is rewritten, they will only steal | |
591 * from the player (tough break). | |
592 */ | |
593 if (on(*att, STEALGOLD)) { | |
594 /* | |
595 * steal some gold | |
596 */ | |
597 register long lastpurse; | |
598 register struct linked_list *item; | |
599 register struct object *obj; | |
600 | |
601 lastpurse = purse; | |
602 purse -= (GOLDCALC * 2); | |
603 if (!save(VS_MAGIC, def, att->t_stats.s_lvl/10)) { | |
604 if (on(*att, ISUNIQUE)) | |
605 purse -= (GOLDCALC * 5); | |
606 else | |
607 purse -= (GOLDCALC * 3); | |
608 } | |
609 if (purse < 0) | |
610 purse = 0; | |
611 if (purse != lastpurse) { | |
612 msg("You lost some gold! "); | |
613 | |
614 /* Give the gold to the thief */ | |
615 for (item=att->t_pack; item != NULL; item=next(item)) { | |
616 obj = OBJPTR(item); | |
617 if (obj->o_type == GOLD) { | |
618 obj->o_count += lastpurse - purse; | |
619 break; | |
620 } | |
621 } | |
622 | |
623 /* Did we do it? */ | |
624 if (item == NULL) { /* Then make some */ | |
625 item = new_item(sizeof *obj); | |
626 obj = OBJPTR(item); | |
627 obj->o_type = GOLD; | |
628 obj->o_count = lastpurse - purse; | |
629 obj->o_hplus = obj->o_dplus = 0; | |
630 strcpy(obj->o_damage,"0d0"); | |
631 strcpy(obj->o_hurldmg,"0d0"); | |
632 obj->o_ac = 11; | |
633 obj->contents = NULL; | |
634 obj->o_group = 0; | |
635 obj->o_flags = 0; | |
636 obj->o_mark[0] = '\0'; | |
637 obj->o_pos = att->t_pos; | |
638 | |
639 attach(att->t_pack, item); | |
640 } | |
641 } | |
642 | |
643 turn_on(*att, ISFLEE); | |
644 turn_on(*att, ISINVIS); | |
645 | |
646 /* It is okay to turn tail */ | |
647 att->t_oldpos = att->t_pos; | |
648 } | |
649 } | |
650 | |
651 /* | |
652 * Stealing happens last since the monster disappears | |
653 * after the act. | |
654 */ | |
655 if (on(*att, STEALMAGIC)) { | |
656 register struct linked_list *list, *steal; | |
657 register struct object *obj; | |
658 register int nobj; | |
659 | |
660 /* | |
661 * steal a magic item, look through the pack | |
662 * and pick out one we like. | |
663 */ | |
664 steal = NULL; | |
665 for (nobj = 0, list = def->t_pack; list != NULL; list = next(list)) | |
666 { | |
667 obj = OBJPTR(list); | |
668 if (!is_current(obj) && | |
669 list != def->t_using && | |
670 obj->o_type != RELIC && | |
671 is_magic(obj) && | |
672 rnd(++nobj) == 0) | |
673 steal = list; | |
674 } | |
675 if (steal != NULL) | |
676 { | |
677 register struct object *obj; | |
678 struct linked_list *item; | |
679 | |
680 obj = OBJPTR(steal); | |
681 if (on(*att, ISUNIQUE)) | |
682 monsters[att->t_index].m_normal = TRUE; | |
683 item = find_mons(att->t_pos.y, att->t_pos.x); | |
684 | |
685 killed(item, FALSE, FALSE, FALSE); /* Remove the attacker */ | |
686 | |
687 if (obj->o_count > 1 && obj->o_group == 0) { | |
688 register int oc; | |
689 | |
690 oc = --(obj->o_count); | |
691 obj->o_count = 1; | |
692 if (def_player) | |
693 msg("%s stole %s!", prname(attname, TRUE), | |
694 inv_name(obj, TRUE)); | |
695 obj->o_count = oc; | |
696 } | |
697 else { | |
698 if (def_player) { | |
699 msg("%s stole %s!", prname(attname, TRUE), | |
700 inv_name(obj, TRUE)); | |
701 | |
702 /* If this is a relic, clear its holding field */ | |
703 if (obj->o_type == RELIC) | |
704 cur_relic[obj->o_which] = 0; | |
705 | |
706 inpack--; | |
707 } | |
708 | |
709 detach(def->t_pack, steal); | |
710 o_discard(steal); | |
711 } | |
712 | |
713 updpack(FALSE, def); | |
714 } | |
715 } | |
716 } | |
717 | |
718 /* Didn't kill the defender */ | |
719 return(0); | |
720 } | |
721 |