| 2812 | } |
| 2813 | |
| 2814 | void |
| 2815 | djinni_from_bottle(struct obj *obj) |
| 2816 | { |
| 2817 | struct monst *mtmp; |
| 2818 | int chance; |
| 2819 | |
| 2820 | if (!(mtmp = makemon(&mons[PM_DJINNI], u.ux, u.uy, MM_NOMSG))) { |
| 2821 | pline("It turns out to be empty."); |
| 2822 | return; |
| 2823 | } |
| 2824 | |
| 2825 | if (!Blind) { |
| 2826 | pline("In a cloud of smoke, %s emerges!", a_monnam(mtmp)); |
| 2827 | pline("%s speaks.", Monnam(mtmp)); |
| 2828 | } else { |
| 2829 | You("smell acrid fumes."); |
| 2830 | pline("%s speaks.", Something); |
| 2831 | } |
| 2832 | |
| 2833 | chance = rn2(5); |
| 2834 | if (obj->blessed) |
| 2835 | chance = (chance == 4) ? rnd(4) : 0; |
| 2836 | else if (obj->cursed) |
| 2837 | chance = (chance == 0) ? rn2(4) : 4; |
| 2838 | /* 0,1,2,3,4: b=80%,5,5,5,5; nc=20%,20,20,20,20; c=5%,5,5,5,80 */ |
| 2839 | |
| 2840 | SetVoice(mtmp, 0, 80, 0); |
| 2841 | switch (chance) { |
| 2842 | case 0: |
| 2843 | verbalize("I am in your debt. I will grant one wish!"); |
| 2844 | /* give a wish and discard the monster (mtmp set to null) */ |
| 2845 | mongrantswish(&mtmp); |
| 2846 | break; |
| 2847 | case 1: |
| 2848 | verbalize("Thank you for freeing me!"); |
| 2849 | (void) tamedog(mtmp, (struct obj *) 0, FALSE); |
| 2850 | break; |
| 2851 | case 2: |
| 2852 | verbalize("You freed me!"); |
| 2853 | mtmp->mpeaceful = TRUE; |
| 2854 | set_malign(mtmp); |
| 2855 | break; |
| 2856 | case 3: |
| 2857 | verbalize("It is about time!"); |
| 2858 | if (canspotmon(mtmp)) |
| 2859 | pline("%s vanishes.", Monnam(mtmp)); |
| 2860 | mongone(mtmp); |
| 2861 | break; |
| 2862 | default: |
| 2863 | verbalize("You disturbed me, fool!"); |
| 2864 | mtmp->mpeaceful = FALSE; |
| 2865 | set_malign(mtmp); |
| 2866 | break; |
| 2867 | } |
| 2868 | } |
| 2869 | |
| 2870 | /* clone a gremlin or mold (2nd arg non-null implies heat as the trigger); |
| 2871 | hit points are cut in half (odd HP stays with original) */ |
no test coverage detected