1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-07-27 07:52:25 +01:00

The Annulus: Anachrononaut quest artifact

Some mods to lightsabers, since the Annulus has a lightsaber mode.
This commit is contained in:
Chris-plus-alphanumericgibberish 2015-09-15 15:24:52 -04:00
parent 448c656754
commit 8d3ea83047
20 changed files with 563 additions and 67 deletions

View file

@ -205,6 +205,19 @@
#define COMMAND_WHIP 22
#define COMMAND_STRIKE 23
#define COMMAND_SABER 24
#define COMMAND_RING 25
#define COMMAND_ARM 26
#define COMMAND_RAY 27
#define COMMAND_BFG 28
#define COMMAND_ANNULUS 29
#define COMMAND_BELL 30
#define COMMAND_BULLETS 31
#define COMMAND_ROCKETS 32
#define COMMAND_BEAM 33
#define COMMAND_ANNUL 34
#define COMMAND_CHARGE 35
struct artifact {
int otyp;
@ -266,6 +279,7 @@ struct artifact {
#define RAISE_UNDEAD (LAST_PROP+40)
#define FALLING_STARS (LAST_PROP+41)
#define THEFT_TYPE (LAST_PROP+42)
#define ANNUL (LAST_PROP+43)
#define is_nameable_artifact(a) (\
(a->spfx & (SPFX_NOGEN|SPFX_RESTR)) == 0\

View file

@ -765,6 +765,12 @@ A("Itlachiayaque", SHIELD_OF_REFLECTION,/*From archeologist patch*/
SMOKE_CLOUD, A_LAWFUL, PM_ARCHEOLOGIST, NON_PM, 3000L,
0,0,0),
A("The Annulus", SILVER_CHAKRAM,
(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL|SPFX_DEFN), (SPFX_HSPDAM), 0,
PHYS(1,1), NO_DFNS, CARY(AD_MAGM),
ANNUL, A_CHAOTIC, PM_ANACHRONONAUT, NON_PM, 3000L,
0,0,0),
A("The Heart of Ahriman", RUBY,
(SPFX_NOGEN|SPFX_RESTR|SPFX_INTEL), (SPFX_REFLECT|SPFX_HSPDAM), 0,
/* this stone does double damage if used as a projectile weapon */

View file

@ -81,6 +81,8 @@ struct objclass {
#define is_damageable(otmp) (is_rustprone(otmp) || is_flammable(otmp) || \
is_rottable(otmp) || is_corrodeable(otmp) || is_evaporable(otmp))
#define is_boomerang(otmp) (objects[(otmp)->otyp].oc_skill == -P_BOOMERANG)
schar oc_subtyp;
#define oc_skill oc_subtyp /* Skills of weapons, spellbooks, tools, gems */
#define oc_armcat oc_subtyp /* for armor */
@ -109,12 +111,12 @@ struct objclass {
schar oc_oc1, oc_oc2;
#define oc_hitbon oc_oc1 /* weapons: "to hit" bonus */
#define w_ammotyp oc_oc2 /* type of ammo taken by ranged weapon */
#define WP_GENERIC 0
#define WP_BULLET 1
#define WP_SHELL 2
#define WP_ROCKET 4
#define WP_GRENADE 8
#define WP_BLASTER 16
#define WP_GENERIC 1
#define WP_BULLET 2
#define WP_SHELL 4
#define WP_ROCKET 8
#define WP_GRENADE 16
#define WP_BLASTER 32
#define a_ac oc_oc1 /* armor class, used in ARM_BONUS in do.c */
#define a_can oc_oc2 /* armor: used in mhitu.c */

View file

@ -32,6 +32,7 @@ STATIC_DCL void FDECL(do_earthquake_at,(int, int, int));
int FDECL(donecromenu, (const char *,struct obj *));
int FDECL(dopetmenu, (const char *,struct obj *));
int FDECL(dolordsmenu, (const char *,struct obj *));
int FDECL(doannulmenu, (const char *,struct obj *));
static NEARDATA schar delay; /* moves left for this spell */
static NEARDATA struct obj *artiptr;/* last/current artifact being used */
@ -2734,6 +2735,7 @@ arti_invoke(obj)
if(obj->age > monstermoves &&
oart->inv_prop != FIRE_SHIKAI &&
oart->inv_prop != SEVENFOLD &&
oart->inv_prop != ANNUL &&
oart->inv_prop != LORDLY
) {
/* the artifact is tired :-) */
@ -2757,6 +2759,7 @@ arti_invoke(obj)
oart->inv_prop != NECRONOMICON &&
oart->inv_prop != SPIRITNAMES &&
oart->inv_prop != LORDLY &&
oart->inv_prop != ANNUL &&
oart->inv_prop != VOID_CHIME &&
oart->inv_prop != SEVENFOLD
)obj->age = monstermoves + (long)(rnz(100)*(Role_if(PM_PRIEST) ? .8 : 1));
@ -4339,6 +4342,205 @@ arti_invoke(obj)
if(lordlydictum >= COMMAND_LADDER) obj->age = monstermoves + (long)(rnz(100)*(Role_if(PM_PRIEST) ? .8 : 1));
} else You_feel("that you should be wielding %s", the(xname(obj)));;
break;
case ANNUL:
if(uwep && uwep == obj){
//struct obj *otmp;
int annulusFunc = doannulmenu("Select function.", obj);
switch(annulusFunc){
case 0:
break;
/*These effects can be used at any time*/
case COMMAND_SABER:
uwep->oclass = TOOL_CLASS;
uwep->altmode = FALSE;
uwep->otyp = LIGHTSABER;
break;
// case COMMAND_ARM:
// if(uwep->lamplit) lightsaber_deactivate(uwep,TRUE);
// uwep->otyp = ARM_BLASTER;
// break;
// case COMMAND_RAY:
// if(uwep->lamplit) lightsaber_deactivate(uwep,TRUE);
// uwep->otyp = RAYGUN;
// break;
case COMMAND_RING:
if(uwep->lamplit) lightsaber_deactivate(uwep,TRUE);
uwep->oclass = RING_CLASS;
uwep->altmode = FALSE;
uwep->otyp = sring;
break;
case COMMAND_KHAKKHARA:
if(uwep->lamplit) lightsaber_deactivate(uwep,TRUE);
uwep->oclass = WEAPON_CLASS;
uwep->altmode = FALSE;
uwep->otyp = SILVER_KHAKKHARA;
break;
case COMMAND_BFG:
if(uwep->lamplit) lightsaber_deactivate(uwep,TRUE);
uwep->oclass = WEAPON_CLASS;
uwep->altmode = WP_MODE_BURST;
uwep->otyp = BFG;
break;
case COMMAND_ANNULUS:
if(uwep->lamplit) lightsaber_deactivate(uwep,TRUE);
uwep->oclass = WEAPON_CLASS;
uwep->altmode = FALSE;
uwep->otyp = SILVER_CHAKRAM;
break;
/*These effects are limited by timeout*/
case COMMAND_BELL:{
boolean wakem = FALSE,
invoking = invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy);
You("ring %s.", the(xname(obj)));
if (Underwater) {
#ifdef AMIGA
amii_speaker( obj, "AhDhGqEqDhEhAqDqFhGw", AMII_MUFFLED_VOLUME );
#endif
pline("But the sound is muffled.");
}
/* charged Bell of Opening */
if (u.uswallow) {
if (!obj->cursed)
(void) openit();
else
pline("%s", nothing_happens);
} else if (obj->cursed) {
coord mm;
mm.x = u.ux;
mm.y = u.uy;
pline("Graves open around you...");
mkundead(&mm, FALSE, NO_MINVENT);
wakem = TRUE;
} else if (invoking) {
pline("%s an unsettling shrill sound...",
Tobjnam(obj, "issue"));
#ifdef AMIGA
amii_speaker( obj, "aefeaefeaefeaefeaefe", AMII_LOUDER_VOLUME );
#endif
u.voidChime = 5;
wakem = TRUE;
} else if (obj->blessed) {
int res = 0;
#ifdef AMIGA
amii_speaker( obj, "ahahahDhEhCw", AMII_SOFT_VOLUME );
#endif
if (uchain) {
unpunish();
res = 1;
}
res += openit();
switch (res) {
case 0: pline("%s", nothing_happens); break;
case 1: pline("%s opens...", Something); break;
default: pline("Things open around you..."); break;
}
} else { /* uncursed */
#ifdef AMIGA
amii_speaker( obj, "AeFeaeFeAefegw", AMII_OKAY_VOLUME );
#endif
if (findit() == 0) pline("%s", nothing_happens);
}
/* charged BofO */
}break;
case COMMAND_BULLETS:{
otmp = mksobj(SILVER_BULLET, TRUE, FALSE);
otmp->blessed = obj->blessed;
otmp->cursed = obj->cursed;
otmp->bknown = obj->bknown;
if (obj->blessed) {
if (otmp->spe < 0) otmp->spe = 0;
otmp->quan += 10+rnd(10);
} else if (obj->cursed) {
if (otmp->spe > 0) otmp->spe = 0;
} else
otmp->quan += rnd(5);
otmp->quan += 20+rnd(20);
otmp->owt = weight(otmp);
otmp = hold_another_object(otmp, "Suddenly %s out.",
aobjnam(otmp, "fall"), (const char *)0);
}break;
case COMMAND_ROCKETS:{
otmp = mksobj(ROCKET, TRUE, FALSE);
otmp->blessed = obj->blessed;
otmp->cursed = obj->cursed;
otmp->bknown = obj->bknown;
if (obj->blessed) {
if (otmp->spe < 0) otmp->spe = 0;
} else if (obj->cursed) {
if (otmp->spe > 0) otmp->spe = 0;
}
otmp->quan = 3+rnd(5);
otmp->owt = weight(otmp);
otmp = hold_another_object(otmp, "Suddenly %s out.",
aobjnam(otmp, "fall"), (const char *)0);
}break;
case COMMAND_BEAM:{
if (!getdir((char *)0)) {
annulusFunc = 0;
break;
}
otmp = mksobj(RAYGUN, TRUE, FALSE);
otmp->blessed = obj->blessed;
otmp->cursed = obj->cursed;
otmp->bknown = obj->bknown;
otmp->altmode = ZT_LIGHTNING;
otmp->ovar1 = 100;
zap_raygun(otmp,1,0);
}break;
case COMMAND_ANNUL:{
struct monst *mtmp = fmon, *ntmp;
You("raise the Annulus into the %s, and it releases a rapidly-expanding ring of energy.", Underwater ? "water" : "air");
for(mtmp; mtmp; mtmp = ntmp){
ntmp = mtmp->nmon;
if(telepathic(mtmp->data) && couldsee(mtmp->mx,mtmp->my)){
killed(mtmp);
} else if(is_magical(mtmp->data) && couldsee(mtmp->mx,mtmp->my)
&& !resist(mtmp, WEAPON_CLASS, 0, NOTELL)
){
killed(mtmp);
} else if(!rn2(5)){
mtmp->mhp -= d(5,15);
if (mtmp->mhp <= 0) xkilled(mtmp, 1);
else {
setmangry(mtmp);
mtmp->mstun = 1;
mtmp->mconf = 1;
}
}
}
if(HTelepat & INTRINSIC){
Your("inner eye is blinded by the flash!");
HTelepat &= ~INTRINSIC;
if (Blind && !Blind_telepat)
see_monsters(); /* Can't sense monsters any more. */
make_stunned(HStun + d(5,15), FALSE);
make_confused(HConfusion + d(5,15), FALSE);
}
}break;
case COMMAND_CHARGE: {
boolean b_effect;
b_effect = obj->blessed &&
(Role_switch == oart->role || !oart->role);
recharge(uwep, b_effect ? 1 : obj->cursed ? -1 : 0);
update_inventory();
break;
}
break;
default:
pline("What is this strange function.");
break;
}
if(annulusFunc >= COMMAND_ANNUL) obj->ovar1 = monstermoves + (long)(rnz(1000)*(Role_if(PM_PRIEST) ? .8 : 1));
else if(annulusFunc >= COMMAND_BELL) obj->ovar1 = monstermoves + (long)(rnz(100)*(Role_if(PM_PRIEST) ? .8 : 1));
} else You_feel("that you should be wielding %s", the(xname(obj)));
break;
case VOID_CHIME:
if(quest_status.killed_nemesis){
int i;
@ -4998,6 +5200,109 @@ struct obj *obj;
return (n > 0) ? selected[0].item.a_int : 0;
}
int
doannulmenu(prompt, obj)
const char *prompt;
struct obj *obj;
{
winid tmpwin;
int n, how;
char buf[BUFSZ];
menu_item *selected;
anything any;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any.a_void = 0; /* zero out all bits */
Sprintf(buf, "Function list:");
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_BOLD, buf, MENU_UNSELECTED);
if(obj->otyp != SILVER_KHAKKHARA && !uarms && !u.twoweap){
Sprintf(buf, "Become a khakkhara");
any.a_int = COMMAND_KHAKKHARA; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'k', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if(obj->otyp != LIGHTSABER){
Sprintf(buf, "Become a lightsaber");
any.a_int = COMMAND_SABER; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
's', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if(obj->oclass != RING_CLASS){
Sprintf(buf, "Become a ring");
any.a_int = COMMAND_RING; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'r', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if(obj->otyp != BFG && !uarms && !u.twoweap){
Sprintf(buf, "Become a gun");
any.a_int = COMMAND_BFG; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'g', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if(obj->otyp != SILVER_CHAKRAM){
Sprintf(buf, "Become a chakram");
any.a_int = COMMAND_ANNULUS; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'c', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if(obj->ovar1 < monstermoves){
if((obj->otyp == SILVER_KHAKKHARA)){
Sprintf(buf, "Ring Out");
any.a_int = COMMAND_BELL; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'R', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if((obj->otyp == BFG)){
Sprintf(buf, "Create Bullets");
any.a_int = COMMAND_BULLETS; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'B', 0, ATR_NONE, buf,
MENU_UNSELECTED);
Sprintf(buf, "Create Rockets");
any.a_int = COMMAND_ROCKETS; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'R', 0, ATR_NONE, buf,
MENU_UNSELECTED);
Sprintf(buf, "Fire Beam");
any.a_int = COMMAND_BEAM; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'F', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if((obj->otyp == SILVER_CHAKRAM)){
Sprintf(buf, "Annul");
any.a_int = COMMAND_ANNUL; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'A', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
if((obj->otyp == LIGHTSABER)){
Sprintf(buf, "Recharge");
any.a_int = COMMAND_CHARGE; /* must be non-zero */
add_menu(tmpwin, NO_GLYPH, &any,
'R', 0, ATR_NONE, buf,
MENU_UNSELECTED);
}
}
end_menu(tmpwin, prompt);
how = PICK_ONE;
n = select_menu(tmpwin, how, &selected);
destroy_nhwindow(tmpwin);
return (n > 0) ? selected[0].item.a_int : 0;
}
STATIC_PTR int
read_necro(VOID_ARGS)
{

View file

@ -117,6 +117,15 @@ boolean restore;
otmp->otyp = SPE_BLANK_PAPER;
curse(otmp);
}
if(is_lightsaber(otmp)){
if(otmp->lamplit) lightsaber_deactivate(otmp,TRUE);
}
if (otmp->oartifact == ART_ANNULUS) { /*Convert the Annulus to an ordinary whatever*/
otmp->oartifact = 0;
otmp->onamelth = 0;
*ONAME(otmp) = '\0';
otmp->owt = weight(otmp);
}
}
}
}

View file

@ -1789,7 +1789,8 @@ int base_uac()
int uac = mons[u.umonnum].ac;
if(uwep){
if(uwep->otyp == RAPIER && arti_shining(uwep))
if((uwep->otyp == RAPIER || (uwep->otyp == LIGHTSABER && uwep->oartifact != ART_ANNULUS && uwep->ovar1 == 0))
&& arti_shining(uwep))
uac -= max(
min(
(ACURR(A_DEX)-13)/4,
@ -1880,7 +1881,9 @@ find_ac()
if (uarmf && uarmf->otyp == pgloves) uac -= 1;
if(uwep){
if(uwep->otyp == RAPIER) uac -= max(
if(uwep->otyp == RAPIER ||
(uwep->otyp == LIGHTSABER && uwep->oartifact != ART_ANNULUS && uwep->ovar1 == 0)
) uac -= max(
min(
(ACURR(A_DEX)-13)/4,
P_SKILL(weapon_type(uwep))-1

View file

@ -185,7 +185,8 @@ int thrown;
if(ammo_and_launcher(obj, launcher) && launcher->oartifact == ART_WRATHFUL_SPIDER) multishot += rn2(8);
if ((long)multishot > obj->quan && obj->oartifact != ART_WINDRIDER
&& obj->oartifact != ART_SICKLE_MOON) multishot = (int)obj->quan;
&& obj->oartifact != ART_SICKLE_MOON && obj->oartifact != ART_ANNULUS
) multishot = (int)obj->quan;
if (shotlimit > 0 && multishot > shotlimit) multishot = shotlimit;
//#ifdef FIREARMS
@ -569,6 +570,7 @@ dofire()
if(uwep && (!uquiver || (is_ammo(uquiver) && !ammo_and_launcher(uquiver, uwep))) && uwep->oartifact &&
(
(uwep->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE) && ACURR(A_STR) == STR19(25)) ||
(uwep->oartifact == ART_ANNULUS && (uwep->otyp == SILVER_CHAKRAM || uwep->otyp == LIGHTSABER)) ||
(uwep->oartifact == ART_AXE_OF_THE_DWARVISH_LORDS && Race_if(PM_DWARF) && ACURR(A_STR) == STR19(25))
// (uwep->oartifact == ART_SICKLE_MOON)
)
@ -1253,6 +1255,7 @@ int thrown;
(obj->oartifact == ART_AXE_OF_THE_DWARVISH_LORDS &&
Race_if(PM_DWARF)) ||
obj->oartifact == ART_WINDRIDER ||
obj->oartifact == ART_ANNULUS ||
obj->oartifact == ART_SICKLE_MOON
) && !impaired
) {
@ -1260,7 +1263,7 @@ int thrown;
Tobjnam(obj, "hit"), ceiling(u.ux,u.uy));
obj = addinv(obj);
(void) encumber_msg();
if(obj->oartifact == ART_WINDRIDER || obj->oartifact == ART_SICKLE_MOON){
if(obj->oartifact == ART_WINDRIDER || obj->oartifact == ART_SICKLE_MOON || obj->oartifact == ART_ANNULUS){
setuqwep(obj);
} else{
setuwep(obj);
@ -1301,10 +1304,10 @@ int thrown;
thrownobj = (struct obj*)0;
return;
} else if(obj->otyp == BOOMERANG && !Underwater) {
} else if(is_boomerang(obj) && !Underwater) {
if(Is_airlevel(&u.uz) || Levitation)
hurtle(-u.dx, -u.dy, 1, TRUE);
mon = boomhit(u.dx, u.dy);
mon = boomhit(obj, u.dx, u.dy);
if(mon == &youmonst) { /* the thing was caught */
exercise(A_DEX, TRUE);
obj = addinv(obj);
@ -1435,13 +1438,14 @@ int thrown;
(obj->oartifact == ART_AXE_OF_THE_DWARVISH_LORDS &&
Race_if(PM_DWARF)) ||
obj->oartifact == ART_SICKLE_MOON ||
obj->oartifact == ART_ANNULUS ||
obj->oartifact == ART_WINDRIDER
)
) {
/* we must be wearing Gauntlets of Power to get here */
if(obj->oartifact != ART_WINDRIDER) sho_obj_return_to_u(obj, startX, startY); /* display its flight */
if(!is_boomerang(obj)) sho_obj_return_to_u(obj, startX, startY); /* display its flight */
if(obj->oartifact != ART_WINDRIDER && (u.ux != startX || u.uy != startY)){
if(!is_boomerang(obj) && (u.ux != startX || u.uy != startY)){
if(flooreffects(obj,startX,startY,"fall")) return;
obj_no_longer_held(obj);
if (mon && mon->isshk && is_pick(obj)) {
@ -1963,7 +1967,7 @@ int thrown;
}
}
} else {
if (otyp == BOOMERANG) /* arbitrary */
if (is_boomerang(obj)) /* arbitrary */
tmp += 4;
else if (throwing_weapon(obj)) /* meant to be thrown */
tmp += 2;

View file

@ -623,6 +623,7 @@ register struct obj *obj;
obj->otyp == BELL_OF_OPENING ||
obj->oartifact == ART_SILVER_KEY ||
obj->oartifact == ART_PEN_OF_THE_VOID ||
obj->oartifact == ART_ANNULUS ||
(obj->oartifact >= ART_FIRST_KEY_OF_LAW && obj->oartifact <= ART_THIRD_KEY_OF_NEUTRALITY) ||
obj->otyp == SPE_BOOK_OF_THE_DEAD) {
/* player might be doing something stupid, but we

View file

@ -1149,9 +1149,9 @@ physical:
if(resist_attacks(mdef->data))
tmp = 0;
/* WAC Weres get seared */
if(otmp && objects[otmp->otyp].oc_material == SILVER &&
(hates_silver(pd))) {
tmp += rnd(20);
if(otmp && (objects[otmp->otyp].oc_material == SILVER || arti_silvered(otmp)) && hates_silver(pd) &&
!(is_lightsaber(otmp) && otmp->lamplit && otmp->oartifact != ART_ANNULUS)
) {
if (vis) pline("The silver sears %s!", mon_nam(mdef));
}
if (otmp->oartifact) {

View file

@ -1357,9 +1357,11 @@ hitmu(mtmp, mattk)
dmg = rnd(2);
} else dmg += dmgval(otmp, &youmonst, 0);
if (objects[otmp->otyp].oc_material == SILVER &&
if (otmp && (objects[otmp->otyp].oc_material == SILVER || arti_silvered(otmp)) &&
!(u.sealsActive&SEAL_EDEN) &&
maybe_polyd(hates_silver(youmonst.data), Race_if(PM_VAMPIRE))) {
maybe_polyd(hates_silver(youmonst.data), Race_if(PM_VAMPIRE)) &&
!(is_lightsaber(otmp) && otmp->lamplit && otmp->oartifact != ART_ANNULUS)
) {
pline("The silver sears your flesh!");
}

View file

@ -548,9 +548,9 @@ boolean artif;
blessorcurse(otmp, 2);
break;
case DOUBLE_LIGHTSABER:
otmp->altmode = FALSE;
case LIGHTSABER:
case BEAMSWORD:
otmp->altmode = FALSE;
otmp->lamplit = 0;
otmp->age = (long) rn1(50000,100000);
blessorcurse(otmp, 2);
@ -561,6 +561,7 @@ boolean artif;
add_to_container(otmp, gem);
container_weight(otmp);
}
otmp->ovar1 = random_saber_hilt();
break;
case CHEST:
case LARGE_BOX:
@ -1295,6 +1296,7 @@ register struct obj *obj;
{
int wt = objects[obj->otyp].oc_weight;
if(obj->oartifact == ART_ROD_OF_LORDLY_MIGHT) wt = objects[MACE].oc_weight;
else if(obj->oartifact == ART_ANNULUS) wt = objects[BFG].oc_weight;
else if(obj->oartifact == ART_SCEPTRE_OF_LOLTH) wt = 3*objects[MACE].oc_weight;
else if(obj->oartifact == ART_ROD_OF_THE_ELVISH_LORDS) wt = objects[ELVEN_MACE].oc_weight;
else if(obj->oartifact == ART_EARTH_CRYSTAL){

View file

@ -3,6 +3,12 @@
/* NetHack may be freely redistributed. See license for details. */
#include "hack.h"
#include "artifact.h"
#ifdef OVLB
#include "artilist.h"
#else
STATIC_DCL struct artifact artilist[];
#endif
/* "an uncursed greased partly eaten guardian naga hatchling [corpse]" */
#define PREFIX 125 /* (56) */
@ -83,16 +89,28 @@ NEARDATA struct colorTextClr LightsaberColor[] = {
{"red",CLR_RED} /*violet glass*/
};
// STATIC_OVL char *SaberHilts[] = {
// "This %s has a curved hilt, making it particularly suited for use in duels.",
// "This %s's grip is composed of a hard, woody substance.",
// "This %s's grip is composed of verticle black ridges.",
// "This %s is fasioned to appear much like a branch of coral.",
// "This %s has an electrum grip and pommel.",
// "There is a winged blade of light carved into the pommel of this %s.",
// "There is a ring of bronze sea-creatures above the grip of this %s.",
// "This %s is quite intricate in its design, covered in delicate runes and inlaid with black markings."
// }
STATIC_OVL char *SaberHilts[] = {
"This %s has a curved hilt, making it particularly suited for use in duels.",
"This %s has a classic grip and exposed emitter disk.",
"This %s projects a single quillon blade.",
"This %s projects a pair of quillon blades.",
"This %s has smooth, flowing design.",
"This %s has smooth hilt with a recessed emitter disk.",
"Six little claws grip the emitter disk of this %s.",
"This %s's grip is composed of a hard, woody substance.",
"This %s's grip is a set of verticle black ridges.",
"This %s's hilt is fasioned to appear much like a branch of coral.",
"This %s has an electrum grip and pommel.",
"This %s has a black grip and silver details.",
"This %s has a long, fabric-wrapped grip and jade buttons.",
"This %s has a rough, worn-looking leather grip.",
"The focusing chamber of this %s can be seen through a viewport.",
"A thin red ribbon hangs from the pommel of this %s.",
"This %s has a crude hilt fashoned from crystalized metal.",
"There is a winged blade of light carved into the pommel of this %s.",
"There is a ring of bronze sea-creatures above the grip of this %s.",
"This %s is quite intricate in its design, covered in delicate runes and inlaid with black markings.",
};
STATIC_OVL struct Jitem ObscureJapanese_items[] = {
{ BATTLE_AXE, "ono" },
@ -211,9 +229,24 @@ char *
lightsaber_colorText(otmp)
struct obj *otmp;
{
if(otmp->oartifact == ART_ANNULUS) return Hallucination ? hcolor(0) : "silver";
return Hallucination ? hcolor(0) : LightsaberColor[((int)otmp->cobj->otyp) - MAGICITE_CRYSTAL].colorText;
}
char *
lightsaber_hiltText(otmp)
struct obj *otmp;
{
if(otmp->oartifact == ART_ANNULUS) return "This %s is just a hollow silver pipe.";
return SaberHilts[(int)otmp->ovar1];
}
int
random_saber_hilt()
{
return rn2(SIZE(SaberHilts));
}
char *
obj_typename(otyp)
register int otyp;
@ -926,7 +959,9 @@ plus:
Strcat(prefix, sitoa(obj->spe));
Strcat(prefix, " ");
}
if(obj->known && obj->oartifact == ART_ROD_OF_LORDLY_MIGHT){
if(obj->known && obj->oartifact &&
(oart->inv_prop == LORDLY || oart->inv_prop == ANNUL)
){
Sprintf(eos(bp), " (%s)", OBJ_NAME(objects[obj->otyp]));
}
//#ifdef FIREARMS
@ -947,7 +982,7 @@ plus:
if (obj->lamplit){
if(obj->age > 1000) Strcat(bp, " (lit)");
else Strcat(bp, " (flickering)");
if(obj->cobj){
if(obj->cobj || obj->oartifact == ART_ANNULUS){
Strcat(prefix, lightsaber_colorText(obj));
Strcat(prefix, " ");
}
@ -2028,6 +2063,7 @@ const char *oldstr;
!BSTRCMP(bp, p-5, "Chaos") ||
!BSTRCMPI(bp, p-11, "Aesculapius") || /* staff */
!BSTRCMPI(bp, p-7, "Orpheus") || /* lyre */
!BSTRCMPI(bp, p-7, "Annulus") || /* Ring */
!BSTRCMPI(bp, p-8, "Longinus") || /* spear */
!BSTRCMPI(bp, p-13, "Water Flowers") || /* boots */
!BSTRCMPI(bp, p-14, "Dwarvish Lords") || /* axe */

View file

@ -1511,7 +1511,9 @@ boolean countem;
for(cobj = level.objects[x][y]; cobj; cobj = nobj) {
nobj = cobj->nexthere;
if(Is_container(cobj) || is_lightsaber(cobj)) {
if(Is_container(cobj) ||
(is_lightsaber(cobj) && cobj->oartifact != ART_ANNULUS)
) {
container_count++;
if (!countem) break;
}
@ -1695,11 +1697,14 @@ lootcont:
You("carefully open %s...", the(xname(cobj)));
timepassed |= use_container(cobj, 0);
if (multi < 0) return 1; /* chest trap */
} else if(is_lightsaber(cobj)){
timepassed |= use_lightsaber(cobj, 0);
if(timepassed) underfoot = TRUE;
}
}
} else if(is_lightsaber(cobj) && cobj->oartifact != ART_ANNULUS){
Sprintf(qbuf, "There is %s here, open it?",an(xname(cobj)));
c = ynq(qbuf);
if (c == 'q') return (timepassed);
if (c == 'n') continue;
timepassed |= use_lightsaber(cobj, 0);
if(timepassed) underfoot = TRUE;
}
}
if (any) c = 'y';
} else if (Confusion) {
@ -1931,6 +1936,7 @@ register struct obj *obj;
obj->oartifact == ART_SILVER_KEY ||
(obj->oartifact >= ART_FIRST_KEY_OF_LAW && obj->oartifact <= ART_THIRD_KEY_OF_NEUTRALITY) ||
obj->oartifact == ART_PEN_OF_THE_VOID ||
obj->oartifact == ART_ANNULUS ||
obj->otyp == SPE_BOOK_OF_THE_DEAD) {
/* Prohibit Amulets in containers; if you allow it, monsters can't
* steal them. It also becomes a pain to check to see if someone

View file

@ -43,7 +43,9 @@ doread()
scroll = getobj(readable, "read");
if(!scroll) return(0);
if(scroll->oartifact && !(scroll->oclass == SCROLL_CLASS) && !arti_mandala(scroll)){
if((scroll->oartifact && !(scroll->oclass == SCROLL_CLASS) && !arti_mandala(scroll))
|| scroll->otyp==LIGHTSABER
){
if(scroll->oartifact == ART_ROD_OF_SEVEN_PARTS){
if (Blind) {
You_cant("see the writing!");
@ -184,6 +186,14 @@ doread()
if (i == MAXSPELL) impossible("Too many spells memorized!");
return 1;
}
} else if(scroll->otyp == LIGHTSABER){
if (Blind) {
You_cant("see it!");
return 0;
} else {
pline(lightsaber_hiltText(scroll),xname(scroll));
}
return(1);
} else {
pline(silly_thing_to, "read");
return(0);
@ -585,7 +595,8 @@ int curse_bless;
boolean is_on = (obj == uleft || obj == uright);
/* destruction depends on current state, not adjustment */
if (obj->spe > rn2(7) || obj->spe <= -5) {
if (obj->spe > (6-rnl(7)) || obj->spe <= -5) {
if(obj->oartifact != ART_ANNULUS){
Your("%s %s momentarily, then %s!",
xname(obj), otense(obj,"pulsate"), otense(obj,"explode"));
if (is_on) Ring_gone(obj);
@ -595,6 +606,17 @@ int curse_bless;
} else {
long mask = is_on ? (obj == uleft ? LEFT_RING :
RIGHT_RING) : 0L;
Your("%s %s momentarily!", xname(obj), otense(obj,"pulsate"));
/* cause attributes and/or properties to be updated */
if (is_on) Ring_off(obj);
obj->spe = 0; /* update the ring while it's off */
if (is_on) setworn(obj, mask), Ring_on(obj);
/* oartifact: if a touch-sensitive artifact ring is
ever created the above will need to be revised */
}
} else {
long mask = is_on ? (obj == uleft ? LEFT_RING :
RIGHT_RING) : 0L;
Your("%s spins %sclockwise for a moment.",
xname(obj), s < 0 ? "counter" : "");
/* cause attributes and/or properties to be updated */

View file

@ -66,7 +66,7 @@ const struct Role roles[] = {
PM_ANACHRONIST, NON_PM, NON_PM,
PM_SARA__THE_LAST_ORACLE, PM_TROOPER, PM_MINION_OF_HUHETOTL,
PM_DOPPELGANGER, PM_MIND_FLAYER, S_TRAPPER, S_UMBER,
ART_ITLACHIAYAQUE,
ART_ANNULUS,
MH_HUMAN|MH_ELF|MH_VAMPIRE | ROLE_MALE|ROLE_FEMALE |
ROLE_NEUTRAL|ROLE_CHAOTIC,
/* Str Int Wis Dex Con Cha */

View file

@ -285,7 +285,7 @@ struct obj *book2;
else arti_cursed = TRUE;
}
}
if(u.voidChime && u.sealsActive&SEAL_OTIAX){
if(u.voidChime && (u.sealsActive&SEAL_OTIAX || Role_if(PM_ANACHRONONAUT))){
arti2_primed = TRUE;
}
if(!arti2_primed && !arti_cursed && uwep && uwep->oartifact == ART_SILVER_KEY){
@ -999,6 +999,33 @@ docast()
}
}
}
if(uwep && uwep->oartifact == ART_ANNULUS && uwep->otyp == SILVER_CHAKRAM){
int i;
for (i = 0; i < MAXSPELL; i++) {
if (spellid(i) == SPE_MAGIC_MISSILE) {
if(spl_book[i].sp_know < 1) spl_book[i].sp_know = 1;
break;
}
if (spellid(i) == NO_SPELL) {
spl_book[i].sp_id = SPE_MAGIC_MISSILE;
spl_book[i].sp_lev = objects[SPE_MAGIC_MISSILE].oc_level;
spl_book[i].sp_know = 1;
break;
}
}
for (i = 0; i < MAXSPELL; i++) {
if (spellid(i) == SPE_FORCE_BOLT) {
if(spl_book[i].sp_know < 1) spl_book[i].sp_know = 1;
break;
}
if (spellid(i) == NO_SPELL) {
spl_book[i].sp_id = SPE_FORCE_BOLT;
spl_book[i].sp_lev = objects[SPE_FORCE_BOLT].oc_level;
spl_book[i].sp_know = 1;
break;
}
}
}
if (getspell(&spell_no))
return spelleffects(spell_no, FALSE, 0);
@ -3324,15 +3351,19 @@ boolean atme;
pline("It invokes nightmarish images in your mind...");
spell_backfire(spell);
return(0);
} else if (spellknow(spell) <= 200 &&
!(spellid(spell) == SPE_LIGHTNING_BOLT || !uarmh || uarmh->oartifact != ART_STORMHELM)
) { /* 1% */
} else if (
!(spellid(spell) == SPE_LIGHTNING_BOLT && uarmh && uarmh->oartifact == ART_STORMHELM) &&
!((spellid(spell) == SPE_FORCE_BOLT || spellid(spell) == SPE_MAGIC_MISSILE) &&
uwep && uwep->oartifact == ART_ANNULUS && uwep->otyp == SILVER_CHAKRAM)
) {
if(spellknow(spell) <= 200) { /* 1% */
You("strain to recall the spell.");
} else if (spellknow(spell) <= 1000 &&
!(spellid(spell) == SPE_LIGHTNING_BOLT || !uarmh || uarmh->oartifact != ART_STORMHELM)
) { /* 5% */
Your("knowledge of this spell is growing faint.");
}
}
energy = (spellev(spell) * 5); /* 5 <= energy <= 35 */
if (!Race_if(PM_INCANTIFIER) && u.uhunger <= 10 && spellid(spell) != SPE_DETECT_FOOD) {
@ -3912,6 +3943,11 @@ int spell;
int difficulty;
int skill;
if(
((spellid(spell) == SPE_FORCE_BOLT || spellid(spell) == SPE_MAGIC_MISSILE) &&
uwep && uwep->oartifact == ART_ANNULUS && uwep->otyp == SILVER_CHAKRAM)
) return 100;
/* Calculate intrinsic ability (splcaster) */
splcaster = urole.spelbase;

View file

@ -803,6 +803,11 @@ int thrown;
if(u.specialSealsActive&SEAL_DAHLVER_NAR) tmp += d(2,6)+min(u.ulevel/2,(u.uhpmax - u.uhp)/10);
if(uarmg && uarmg->otyp == tgloves) tmp += 1;
valid_weapon_attack = (tmp > 1);
//The Annulus is very heavy
if(uright && uright->oartifact == ART_ANNULUS) tmp = (tmp+uright->spe)*2;
else if(uleft && uleft->oartifact == ART_ANNULUS) tmp = (tmp+uleft->spe)*2;
if(uarm && uarm->otyp <= YELLOW_DRAGON_SCALES && uarm->otyp >= GRAY_DRAGON_SCALE_MAIL){
dragon_hit(mon, uarm, uarm->otyp, &tmp, &needpoismsg, &poiskilled, &druggedmon);
}
@ -1188,7 +1193,7 @@ int thrown;
}
if ((objects[obj->otyp].oc_material == SILVER || arti_silvered(obj) ||
(thrown && obj->otyp == SHURIKEN && uwep && uwep->oartifact == ART_SILVER_STARLIGHT) )
&& hates_silver(mdat) && !(is_lightsaber(obj) && obj->lamplit)) {
&& hates_silver(mdat) && !(is_lightsaber(obj) && obj->lamplit && obj->oartifact != ART_ANNULUS)) {
if(obj->oartifact == ART_SUNSWORD) sunmsg = TRUE;
else silvermsg = TRUE;
silverobj = TRUE;
@ -3807,7 +3812,9 @@ dobpois:
}
} break;
case AD_UNKNWN:
if(uwep && uwep->oartifact && uwep->oartifact != ART_SILVER_KEY && uwep->oartifact != ART_PEN_OF_THE_VOID && CountsAgainstGifts(uwep->oartifact)){
if(uwep && uwep->oartifact && uwep->oartifact != ART_SILVER_KEY && uwep->oartifact != ART_ANNULUS
&& uwep->oartifact != ART_PEN_OF_THE_VOID && CountsAgainstGifts(uwep->oartifact)
){
You_feel("%s tug gently on your %s.",mon_nam(mon), ONAME(uwep));
if(yn("Release it?")=='n'){
You("hold on tight.");

View file

@ -169,7 +169,7 @@ struct monst *mon;
/* Put weapon specific "to hit" bonuses in below: */
tmp += objects[otmp->otyp].oc_hitbon;
if (otmp->otyp == DOUBLE_LIGHTSABER && otmp->altmode) tmp += objects[otmp->otyp].oc_hitbon;
if (is_lightsaber(otmp) && otmp->altmode) tmp += objects[otmp->otyp].oc_hitbon;
/* Put weapon vs. monster type "to hit" bonuses in below: */
@ -326,7 +326,7 @@ int spec;
break;
case LIGHTSABER:
case BEAMSWORD:
tmp += d(2, objects[otyp].oc_wldam)+2*otmp->spe;
tmp += d(2, objects[otyp].oc_wldam);
otmp->age -= 100;
if(otmp->oartifact == ART_ATMA_WEAPON &&
!Drain_resistance
@ -337,12 +337,16 @@ int spec;
((float)u.mh)/u.mhmax :
((float)u.uhp)/u.uhpmax;
}
if(otmp->altmode){ //Probably just the Annulus
tmp += d(3, 3);
otmp->age -= 100;
}
break;
case DOUBLE_LIGHTSABER:
tmp += d(2, objects[otyp].oc_wldam)+2*otmp->spe;
tmp += d(2, objects[otyp].oc_wldam);
otmp->age -= 100;
if (otmp->altmode){
tmp += d(3, objects[otyp].oc_wldam)+3*otmp->spe;
tmp += d(3, objects[otyp].oc_wldam);
otmp->age -= 100;
}
break;
@ -428,7 +432,7 @@ int spec;
break;
case LIGHTSABER:
case BEAMSWORD:
tmp += d(2, objects[otyp].oc_wsdam)+2*otmp->spe;
tmp += d(2, objects[otyp].oc_wsdam);
otmp->age -= 100;
if(otmp->oartifact == ART_ATMA_WEAPON &&
!Drain_resistance
@ -439,12 +443,16 @@ int spec;
((float)u.mh)/u.mhmax :
((float)u.uhp)/u.uhpmax;
}
if(otmp->altmode){ //Probably just the Annulus
tmp += d(3, 3);
otmp->age -= 100;
}
break;
case DOUBLE_LIGHTSABER:
tmp += d(2, objects[otyp].oc_wsdam)+2*otmp->spe;
tmp += d(2, objects[otyp].oc_wsdam);
otmp->age -= 100;
if (otmp->altmode){
tmp += d(3, objects[otyp].oc_wsdam)+3*otmp->spe;
tmp += d(3, objects[otyp].oc_wsdam);
otmp->age -= 100;
}
break;
@ -464,15 +472,20 @@ int spec;
}
if (Is_weapon) {
if(otmp->oartifact != ART_TENTACLE_ROD){
if(is_lightsaber(otmp)){
if(Race_if(PM_ORC)){
tmp += 3*max((u.ulevel+1)/3,otmp->spe);
} else tmp += 3*otmp->spe;
} else if(otmp->oartifact != ART_TENTACLE_ROD){
if(Race_if(PM_ORC)){
tmp += max((u.ulevel+1)/3,otmp->spe);
} else tmp += otmp->spe;
}
if (otmp->otyp == DOUBLE_LIGHTSABER && otmp->altmode){
if (is_lightsaber(otmp) && otmp->altmode){
if(Race_if(PM_ORC)){
tmp += max((u.ulevel+1)/3,otmp->spe);
} else tmp += otmp->spe;
tmp += 3*max((u.ulevel+1)/3,otmp->spe);
} else tmp += 3*otmp->spe;
}
/* negative enchantment mustn't produce negative damage */
if (tmp < 0) tmp = 0;
@ -509,10 +522,15 @@ int spec;
bonus += rnd(4);
if (is_axe(otmp) && is_wooden(ptr))
bonus += rnd(4);
if ((objects[otyp].oc_material == SILVER || arti_silvered(otmp)) && hates_silver(ptr)){
if ((objects[otyp].oc_material == SILVER || arti_silvered(otmp))
&& (hates_silver(ptr) || (youdefend && maybe_polyd(hates_silver(youmonst.data), Race_if(PM_VAMPIRE))))
&& !(is_lightsaber(otmp) && otmp->lamplit && otmp->oartifact != ART_ANNULUS)
&& (!youdefend || !(u.sealsActive&SEAL_EDEN))
){
if(otyp == SILVER_KHAKKHARA) bonus += d(rnd(3),20);
else if(otmp->oartifact == ART_PEN_OF_THE_VOID && mvitals[PM_ACERERAK].died > 0) bonus += d(2,20);
else if(otmp->oartifact == ART_SILVER_STARLIGHT) bonus += d(2,20);
else if(otmp->altmode && otmp->oartifact == ART_ANNULUS && is_lightsaber(otmp)) bonus += d(2,20);
else bonus += rnd(20);
}
@ -938,8 +956,11 @@ register struct monst *mtmp;
/* Weapons in order of preference */
static const NEARDATA short hwep[] = {
CORPSE, /* cockatrice corpse */
DOUBLE_LIGHTSABER/*6d8*/, BEAMSWORD/*3d10*/,
DOUBLE_LIGHTSABER/*6d8*/,
BEAMSWORD/*3d10*/,
FORCE_PIKE,/*2d6+6/2d8+8*/
LIGHTSABER/*3d8*/,
VIBROBLADE,/*2d6+3/2d8+4*/
CRYSTAL_SWORD/*2d8/2d12*/,
DROVEN_GREATSWORD/*1d18/1d30*/,
TSURUGI/*1d16/1d8+2d6*/,
@ -1273,7 +1294,10 @@ struct monst * mon;
}
} else {
/* Double Lightsaber in single mode? Ignite second blade */
if (obj->otyp == DOUBLE_LIGHTSABER && !obj->altmode) {
if (is_lightsaber(obj) &&
(obj->otyp == DOUBLE_LIGHTSABER || obj->oartifact == ART_ANNULUS) &&
!obj->altmode
) {
/* Do we want to activate dual bladed mode? */
if (!obj->altmode && (!obj->cursed || rn2(4))) {
if (canseemon(mon)) pline("%s ignites the second blade of %s.",
@ -1337,7 +1361,17 @@ struct obj *otmp;
(otmp->oartifact==ART_PEN_OF_THE_VOID && otmp->ovar1&SEAL_MARIONETTE && mvitals[PM_ACERERAK].died > 0)
)) bonus *= 2;
if(uwep && otmp==uwep && otmp->otyp==RAPIER){
if(uwep && otmp==uwep && (otmp->otyp==RAPIER || (otmp->otyp == LIGHTSABER && otmp->oartifact != ART_ANNULUS && otmp->ovar1 == 0))){
int dex = ACURR(A_DEX);
bonus/=2; /*Half strength bonus/penalty*/
bonus += (dex-11)/2;
}
if(u.sealsActive&SEAL_DANTALION) bonus += max(0,(ACURR(A_INT)-10)/2);
return bonus;
}
int dex = ACURR(A_DEX);
bonus/=2; /*Half strength bonus/penalty*/

View file

@ -192,7 +192,9 @@ struct obj *wep;
pline("%s to %s%s!", Tobjnam(wep, "begin"),
(wep->blessed ? "shine very" : "glow"), (wep->cursed ? "" : " brilliantly"));
}
if(stealthy && wep->otyp == SILVER_KHAKKHARA) pline("The silver rings chime together.");
if(stealthy && wep->otyp == SILVER_KHAKKHARA) (wep->oartifact == ART_ANNULUS) ?
pline("The hollow silver rod chimes at the slightest touch.") :
pline("The silver rings chime together.");
else if(!stealthy && Stealth) pline("Now you can move stealthily.");
#if 0
@ -764,6 +766,7 @@ register int amount;
if(((uwep->spe > safelim && amount >= 0) || (uwep->spe < -safelim && amount < 0))
&& rn2(3) && uwep->oartifact != ART_ROD_OF_SEVEN_PARTS
&& uwep->oartifact != ART_PEN_OF_THE_VOID
&& uwep->oartifact != ART_ANNULUS
) {
if (!Blind)
Your("%s %s for a while and then %s.",
@ -800,10 +803,11 @@ register int amount;
/* an elven magic clue, cookie@keebler */
/* elven weapons vibrate warningly when enchanted beyond a limit */
if ((uwep->otyp == CRYSTAL_SWORD ? (uwep->spe > 8) : (uwep->spe > 5)) && uwep->oartifact != ART_PEN_OF_THE_VOID &&
if ((uwep->otyp == CRYSTAL_SWORD ? (uwep->spe > 8) : (uwep->spe > 5))
&& uwep->oartifact != ART_PEN_OF_THE_VOID && uwep->oartifact != ART_ANNULUS &&
(is_elven_weapon(uwep) || uwep->oartifact || !rn2(7)) &&
uwep->oartifact != ART_ROD_OF_SEVEN_PARTS)
Your("%s unexpectedly.",
uwep->oartifact != ART_ROD_OF_SEVEN_PARTS
) Your("%s unexpectedly.",
aobjnam(uwep, "suddenly vibrate"));
if(uwep->oartifact == ART_ROD_OF_SEVEN_PARTS && uwep->spe > 7){
@ -814,6 +818,8 @@ register int amount;
uwep->spe = 5;
} else if(uwep->oartifact == ART_PEN_OF_THE_VOID && uwep->spe > 10){
uwep->spe = 10;
} else if(uwep->oartifact == ART_ANNULUS && uwep->spe > 7){
uwep->spe = 7;
}
return(1);

View file

@ -1141,6 +1141,7 @@ int ochance, achance; /* percent chance for ordinary objects, artifacts */
obj->oartifact == ART_SILVER_KEY ||
(obj->oartifact >= ART_FIRST_KEY_OF_LAW && obj->oartifact <= ART_THIRD_KEY_OF_NEUTRALITY) ||
obj->oartifact == ART_PEN_OF_THE_VOID ||
obj->oartifact == ART_ANNULUS ||
(obj->otyp == CORPSE && is_rider(&mons[obj->corpsenm]))) {
return TRUE;
} else {