* creature (usually hero) tries to touch (pick up or wield) an artifact obj. * Returns 0 if the object refuses to be touched. * This routine does not change any object chains. * Ignores such things as gauntlets, assuming the artifact is not * fooled by such trappings. */
| 905 | * fooled by such trappings. |
| 906 | */ |
| 907 | int |
| 908 | touch_artifact(struct obj *obj, struct monst *mon) |
| 909 | { |
| 910 | const struct artifact *oart = get_artifact(obj); |
| 911 | boolean badclass, badalign, self_willed, yours; |
| 912 | |
| 913 | touch_blasted = FALSE; |
| 914 | if (oart == &artilist[ART_NONARTIFACT]) |
| 915 | return 1; |
| 916 | |
| 917 | yours = (mon == &gy.youmonst); |
| 918 | /* all quest artifacts are self-willed; if this ever changes, `badclass' |
| 919 | will have to be extended to explicitly include quest artifacts */ |
| 920 | self_willed = ((oart->spfx & SPFX_INTEL) != 0); |
| 921 | if (yours) { |
| 922 | badclass = self_willed |
| 923 | && ((oart->role != NON_PM && !Role_if(oart->role)) |
| 924 | || (oart->race != NON_PM && !Race_if(oart->race))); |
| 925 | badalign = ((oart->spfx & SPFX_RESTR) != 0 |
| 926 | && oart->alignment != A_NONE |
| 927 | && (oart->alignment != u.ualign.type |
| 928 | || u.ualign.record < 0)); |
| 929 | } else if (!is_covetous(mon->data) && !is_mplayer(mon->data)) { |
| 930 | badclass = self_willed && oart->role != NON_PM |
| 931 | && oart != &artilist[ART_EXCALIBUR]; |
| 932 | badalign = (oart->spfx & SPFX_RESTR) && oart->alignment != A_NONE |
| 933 | && (oart->alignment != mon_aligntyp(mon)); |
| 934 | } else { /* an M3_WANTSxxx monster or a fake player */ |
| 935 | /* special monsters trying to take the Amulet, invocation tools or |
| 936 | quest item can touch anything except `spec_applies' artifacts */ |
| 937 | badclass = badalign = FALSE; |
| 938 | } |
| 939 | /* weapons which attack specific categories of monsters are |
| 940 | bad for them even if their alignments happen to match */ |
| 941 | if (!badalign) |
| 942 | badalign = bane_applies(oart, mon); |
| 943 | |
| 944 | if (((badclass || badalign) && self_willed) |
| 945 | || (badalign && (!yours || !rn2(4)))) { |
| 946 | int dmg, tmp; |
| 947 | char buf[BUFSZ]; |
| 948 | |
| 949 | if (!yours) |
| 950 | return 0; |
| 951 | You("are blasted by %s power!", s_suffix(the(xname(obj)))); |
| 952 | touch_blasted = TRUE; |
| 953 | dmg = d((Antimagic ? 2 : 4), (self_willed ? 10 : 4)); |
| 954 | /* add half (maybe quarter) of the usual silver damage bonus */ |
| 955 | if (objects[obj->otyp].oc_material == SILVER && Hate_silver) |
| 956 | tmp = rnd(10), dmg += Maybe_Half_Phys(tmp); |
| 957 | Sprintf(buf, "touching %s", oart->name); |
| 958 | losehp(dmg, buf, KILLED_BY); /* magic damage, not physical */ |
| 959 | exercise(A_WIS, FALSE); |
| 960 | } |
| 961 | |
| 962 | /* can pick it up unless you're totally non-synch'd with the artifact */ |
| 963 | if (badclass && badalign && self_willed) { |
| 964 | if (yours) { |
no test coverage detected