1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-05-10 17:25:12 +01:00

New race: octopode

Based on http://crawl.chaosforge.org/Octopode to some extent.

-Can wear 8 rings.
--Extra rings fall off if polymorphed.
--Not a valid polymorph form, but it should work.
-Can be wizards, rogues, pirates, acus, or binders.
-Attribute caps:
 Str   Int Wis Dex Con Cha
 18/** 20  18  20  16  16
-Special spell: poison spray.
--Not very useful since they don't have a special way of learning it.
-Human HP and energy growth.
-Radius-2 low light vision.
-Medium sized.  Can wear barded helmets and soft hats, cloaks, dragon
 scales (not scale mail) and waistcloths, shields.
-Extra 1d8 tentacle wrap attack that can drown if over water.
-+level/10 bonus to natural DR and +level/2 bonus to natural AC, to
 compensate for being unable to wear most armour.
--Rings of protection can also compensate, but unlike in DCSS they
  need to be identified and charged first.
-Starts with stone resistance, poison resistance, stealth, swimming,
 magical breathing, waterproofing.
--Stone resistance because it would be unplayable otherwise (no
  gloves).
--Waterproof so swimming is usable.
-Immune to heart-piercing and bisection vorpality (doesn't have any
 special effect) and being ripped apart by Demogorgon (does double damage
 instead).
--Immunity to heart piercing vorpality could be explained by octopodes
  having 3 hearts, but the real reason for this is that they can't wear
  armour that would protect them.
-Weldproof because I didn't implement interactions of curses with
 being able to wear 8 rings.  Unlike the other intrinsics, this is
 only provided from form (you will lose it if you polymorph).
-Immune to glib because of their suckers (and because I didn't
 implement how being able to wear 8 rings interacts with it).
-Can't have rings put on by seduction because I didn't implement it.

Also:
-Parasitized androids are weldproof.
-Enlightenment message for white hlf waterproofing.
This commit is contained in:
Ron Nazarov 2024-04-12 14:30:52 +01:00
parent de8173607f
commit 7dd65d4260
Signed by: noisytoot
GPG key ID: 1D43EF4F4492268B
30 changed files with 477 additions and 248 deletions

View file

@ -588,12 +588,19 @@ E NEARDATA struct obj *invent,
#ifdef TOURIST
*uarmu, /* under-wear, so to speak */
#endif
*uskin, *uamul, *uleft, *uright, *ublindf,
*uskin, *uamul, *ublindf,
*uwep, *uswapwep, *uquiver;
#define URINGS_SIZE 8
E NEARDATA struct obj *urings[URINGS_SIZE]; /* init'd and defined in decl.c */
E NEARDATA const long long ring_index_to_wornmask[URINGS_SIZE]; /* init'd and defined in worn.c */
#define uleft (urings[0])
#define uright (urings[1])
/* Needs to update, so it's redefined each time whenever it's used */
#define ARMOR_SLOTS { uarm, uarmc, uarmf, uarmh, uarmg, uarms, uarmu }
#define WORN_SLOTS { uarm, uarmc, uarmf, uarmh, uarmg, uarms, uarmu, uamul, uleft, uright, ublindf, uwep, uswapwep, uquiver }
#define WORN_SLOTS { uarm, uarmc, uarmf, uarmh, uarmg, uarms, uarmu, uamul, ublindf, uwep, uswapwep, uquiver, \
urings[0], urings[1], urings[2], urings[3], urings[4], urings[5], urings[6], urings[7] }
E NEARDATA struct obj *urope; /* defined only when entangled */
E NEARDATA struct obj *uchain; /* defined only when punished */

View file

@ -628,7 +628,7 @@ E int NDECL(dotakeoff);
E int NDECL(doremring);
E int FDECL(cursed, (struct obj *));
E int FDECL(armoroff, (struct obj *));
E int FDECL(canwearobj, (struct obj *, long *, BOOLEAN_P));
E int FDECL(canwearobj, (struct obj *, long long *, BOOLEAN_P));
E int NDECL(dowear);
E int NDECL(doputon);
E int FDECL(arm_total_bonus, (struct obj *));
@ -904,6 +904,7 @@ E const char* NDECL(get_alignment_adj);
E boolean NDECL(Check_crystal_lifesaving);
E boolean NDECL(Check_iaso_lifesaving);
E boolean NDECL(Check_twin_lifesaving);
E boolean NDECL(Check_ring_lifesaving);
E void FDECL(done, (int));
E void FDECL(container_contents, (struct obj *,BOOLEAN_P,BOOLEAN_P));
#ifdef DUMP_LOG
@ -2114,6 +2115,7 @@ E void NDECL(objects_init);
/* ### objnam.c ### */
E int FDECL(nth_ring_text, (int, char *, size_t));
E const char *FDECL(lightsaber_colorText, (struct obj *));
E int FDECL(lightsaber_colorCLR, (struct obj *));
E char *FDECL(lightsaber_hiltText, (struct obj *));
@ -2365,8 +2367,8 @@ E void FDECL(ugolemeffects, (int,int));
/* ### potion.c ### */
E void FDECL(set_itimeout, (long *,long));
E void FDECL(incr_itimeout, (long *,long));
E void FDECL(set_itimeout, (long long *,long));
E void FDECL(incr_itimeout, (long long *,long));
E long FDECL(itimeout_incr, (long,long));
E void FDECL(make_confused, (long,BOOLEAN_P));
E void FDECL(make_stunned, (long,BOOLEAN_P));
@ -3421,6 +3423,11 @@ E int FDECL(count_wsegs, (struct monst *));
E boolean FDECL(worm_known, (struct monst *));
/* ### worn.c ### */
E int FDECL(count_worn_rings, (boolean));
E int FDECL(uring_otyp_index, (int));
E int FDECL(uring_art_index, (int));
E struct obj *FDECL(uring_otyp, (int));
E struct obj *FDECL(uring_art, (int));
E boolean FDECL(item_has_property, (struct obj *, int));
E void FDECL(get_item_property_list, (int *, struct obj*, int));
E void FDECL(setworn, (struct obj *,long));

View file

@ -284,7 +284,7 @@ struct obj {
long age; /* creation date */
/* in order to prevent alignment problems oextra should
be (or follow) a long int */
long owornmask;
long long owornmask;
/* Weapons and artifacts */
// define W_ARM 0x00000001L /* Body armor */
// define W_ARMC 0x00000002L /* Cloak */

View file

@ -143,44 +143,52 @@
/* Definitions were moved here from obj.h and you.h */
struct prop {
/*** Properties conveyed by objects ***/
long extrinsic;
long long extrinsic;
/* Armor */
# define W_ARM 0x00000001L /* Body armor */
# define W_ARMC 0x00000002L /* Cloak */
# define W_ARMH 0x00000004L /* Helmet/hat */
# define W_ARMS 0x00000008L /* Shield */
# define W_ARMG 0x00000010L /* Gloves/gauntlets */
# define W_ARMF 0x00000020L /* Footwear */
# define W_ARMU 0x00000040L /* Undershirt */
# define W_ARM 0x00000001LL /* Body armor */
# define W_ARMC 0x00000002LL /* Cloak */
# define W_ARMH 0x00000004LL /* Helmet/hat */
# define W_ARMS 0x00000008LL /* Shield */
# define W_ARMG 0x00000010LL /* Gloves/gauntlets */
# define W_ARMF 0x00000020LL /* Footwear */
# define W_ARMU 0x00000040LL /* Undershirt */
# define W_ARMOR (W_ARM | W_ARMC | W_ARMH | W_ARMS | W_ARMG | W_ARMF | W_ARMU)
/* Weapons and artifacts */
# define W_WEP 0x00000100L /* Wielded weapon */
# define W_QUIVER 0x00000200L /* Quiver for (f)iring ammo */
# define W_SWAPWEP 0x00000400L /* Secondary weapon */
# define W_ART 0x00001000L /* Carrying artifact (not really worn) */
# define W_ARTI 0x00002000L /* Invoked artifact (not really worn) */
# define W_WEP 0x00000100LL /* Wielded weapon */
# define W_QUIVER 0x00000200LL /* Quiver for (f)iring ammo */
# define W_SWAPWEP 0x00000400LL /* Secondary weapon */
# define W_ART 0x00001000LL /* Carrying artifact (not really worn) */
# define W_ARTI 0x00002000LL /* Invoked artifact (not really worn) */
/* Amulets, rings, tools, and other items */
# define W_AMUL 0x00010000L /* Amulet */
# define W_RINGL 0x00020000L /* Left ring */
# define W_RINGR 0x00040000L /* Right ring */
# define W_RING (W_RINGL | W_RINGR)
# define W_TOOL 0x00080000L /* Eyewear */
# define W_ACCESSORY (W_AMUL | W_RING| W_TOOL)
# define W_AMUL 0x00010000LL /* Amulet */
# define W_RING0 0x00020000LL /* Ring 0 (left) */
# define W_RING1 0x00040000LL /* Ring 1 (right) */
# define W_RING2 0x00080000LL /* Ring 2 (extra) */
# define W_RING3 0x00100000LL /* Ring 3 (extra) */
# define W_RING4 0x00400000LL /* Ring 4 (extra) */
# define W_RING5 0x00800000LL /* Ring 5 (extra) */
# define W_RING6 0x01000000LL /* Ring 6 (extra) */
# define W_RING7 0x04000000LL /* Ring 7 (extra) */
# define W_RINGL W_RING0
# define W_RINGR W_RING1
# define W_RING (W_RING0 | W_RING1 | W_RING2 | W_RING3 | W_RING4 | W_RING5 | W_RING6 | W_RING7)
# define W_TOOL 0x20000000LL /* Eyewear */
# define W_ACCESSORY (W_AMUL | W_RING | W_TOOL)
#ifdef STEED
# define W_SADDLE 0x00100000L /* KMH -- For riding monsters */
# define W_SADDLE 0x40000000LL /* KMH -- For riding monsters */
#endif
# define W_BALL 0x00200000L /* Punishment ball */
# define W_CHAIN 0x00400000L /* Punishment chain */
# define W_SPIRIT 0x00800000L /* Bound spirit */
# define W_GLYPH 0x01000000L /* Active thought-glyph */
# define W_SKIN I_SPECIAL /* merged into skin */
# define W_WORN (W_ARMOR | W_ACCESSORY)
# define W_BALL 0x0000000080000000LL /* Punishment ball */
# define W_CHAIN 0x0000000100000000LL /* Punishment chain */
# define W_SPIRIT 0x0000000200000000LL /* Bound spirit */
# define W_GLYPH 0x0000000400000000LL /* Active thought-glyph */
# define W_SKIN I_SPECIAL /* merged into skin */
# define W_WORN (W_ARMOR | W_ACCESSORY)
/*** Property is blocked by an object ***/
long blocked; /* Same assignments as extrinsic */
long long blocked; /* Same assignments as extrinsic */
/*** Timeouts, permanent properties, and other flags ***/
long intrinsic;
long long intrinsic;
/* Timed properties */
# define TIMEOUT 0x00ffffffL /* Up to 16 million turns */
# define TIMEOUT_INF 0x00800000L /* If you get this much, it won't decrement. should be a subset of TIMEOUT */

View file

@ -74,7 +74,8 @@
#define SUBOUT_ACU 18 /* ACU tentacle attack */
#define SUBOUT_SALA1 19 /* Sala tuch attack */
#define SUBOUT_SALA2 20 /* Sala hug attack */
#define MAX_SUBOUT 21
#define SUBOUT_OCT 21 /* Octopode tentacle attack */
#define MAX_SUBOUT 22
#define SUBOUT_ARRAY_SIZE (MAX_SUBOUT/8+1)
#endif

View file

@ -22,8 +22,6 @@
#define maybe_polyd(if_so,if_not) (Upolyd ? (if_so) : (if_not))
#define uring_art(art_num) ((uright && uright->oartifact == art_num) || (uleft && uleft->oartifact == art_num))
/*** Resistances to troubles ***/
#define Oona_resistance ((u.oonaenergy == AD_FIRE ? Fire_resistance : u.oonaenergy == AD_COLD ? Cold_resistance : u.oonaenergy == AD_ELEC ? Shock_resistance : FALSE))
/* With intrinsics and extrinsics */
@ -398,9 +396,11 @@
#define HWeldproof u.uprops[WELDPROOF].intrinsic
#define EWeldproof u.uprops[WELDPROOF].extrinsic
#define Weldproof (HWeldproof || EWeldproof || \
is_demon(youracedata) || is_undead(youracedata) || (u.ulycn >= LOW_PM) || (Race_if(PM_ANDROID))\
)
#define Weldproof (HWeldproof || EWeldproof || \
is_demon(youracedata) || is_undead(youracedata) || (u.ulycn >= LOW_PM) || \
Race_if(PM_ANDROID) || Race_if(PM_PARASITIZED_ANDROID) || \
(youracedata->mtyp == PM_OCTOPODE) \
)
/*** Appearance and behavior ***/
#define Adornment u.uprops[ADORNED].extrinsic
@ -643,7 +643,7 @@
/*Note: the rings only give life saving when charged, so it can't be a normal property*/
#define ELifesaved u.uprops[LIFESAVED].extrinsic
#define Lifesaved (ELifesaved || Check_crystal_lifesaving() || Check_iaso_lifesaving() || Check_twin_lifesaving() || (uleft && uleft->otyp == RIN_WISHES && uleft->spe > 0) || (uright && uright->otyp == RIN_WISHES && uright->spe > 0) || (check_mutation(ABHORRENT_SPORE) && !(mvitals[PM_DARK_YOUNG].mvflags & G_GENOD)))
#define Lifesaved (ELifesaved || Check_crystal_lifesaving() || Check_iaso_lifesaving() || Check_twin_lifesaving() || Check_ring_lifesaving() || (check_mutation(ABHORRENT_SPORE) && !(mvitals[PM_DARK_YOUNG].mvflags & G_GENOD)))
#define Necrospellboost (u.uprops[NECROSPELLS].extrinsic)

View file

@ -978,7 +978,8 @@ you_regen_hp()
perX += stone_health();
// fish out of water
if (youracedata->mlet == S_EEL && !is_pool(u.ux, u.uy, youracedata->msize == MZ_TINY) && !Is_waterlevel(&u.uz)) {
if (youracedata->mlet == S_EEL && youracedata->mtyp != PM_OCTOPODE &&
!is_pool(u.ux, u.uy, youracedata->msize == MZ_TINY) && !Is_waterlevel(&u.uz)) {
if (is_pool(u.ux, u.uy, TRUE))
perX -= HEALCYCLE * (youracedata->msize - 1) / (youracedata->msize);
else
@ -996,7 +997,7 @@ you_regen_hp()
if(likes_lava(youracedata) && levl[u.ux][u.uy].typ == LAVAPOOL){
perX += HEALCYCLE;
}
// regeneration 'trinsic
if (Regeneration){
perX += HEALCYCLE;

View file

@ -2641,7 +2641,7 @@ register struct obj *otmp;
boolean on;
long wp_mask;
{
long *mask = 0;
long long *mask = 0;
register const struct artifact *oart = get_artifact(otmp);
int oartifact = otmp->oartifact;
uchar dtyp;
@ -6984,9 +6984,9 @@ boolean printmessages; /* print generic elemental damage messages */
/* apply other damage modifiers */
if (method == VORPAL_BEHEAD && (noncorporeal(pd) || amorphous(pd)))
vorpaldamage = 0;
if ((method == VORPAL_BISECT) && (bigmonst(pd) || notonhead))
if ((method == VORPAL_BISECT) && (bigmonst(pd) || notonhead || pd->mtyp == PM_OCTOPODE))
vorpaldamage = basedmg;
if ((method == VORPAL_PIERCE) && (!has_blood_mon(mdef) || !(pd->mflagsb&MB_BODYTYPEMASK) || noncorporeal(pd) || amorphous(pd)))
if ((method == VORPAL_PIERCE) && (!has_blood_mon(mdef) || !(pd->mflagsb&MB_BODYTYPEMASK) || noncorporeal(pd) || amorphous(pd) || pd->mtyp == PM_OCTOPODE))
vorpaldamage = basedmg;
/* Are we sufficiently lethal for a vorpal kill? */
@ -12304,14 +12304,13 @@ arti_invoke(obj)
case MORGOTH:{
int base_otyp = find_good_iring();
int new_otyp = obj->otyp == base_otyp ? RIN_NOTHING : base_otyp;
boolean worn_left = obj == uleft;
boolean worn_right = obj == uright;
long long wornmask = obj->owornmask;
pline("%s suddenly seems much more %s.", artilist[obj->oartifact].name,
new_otyp == RIN_NOTHING ? "boring" : "interesting");
if (worn_left || worn_right) Ring_off(obj);
if (wornmask) Ring_off(obj);
obj->otyp = new_otyp;
if (worn_left || worn_right) {
setworn(obj, worn_left ? LEFT_RING : RIGHT_RING);
if (wornmask) {
setworn(obj, wornmask);
Ring_on(obj);
}
if (obj->otyp == RIN_NOTHING) makeknown(RIN_NOTHING);

View file

@ -29,7 +29,7 @@ const char * const plusattr[] = {
static
const struct innate {
schar ulevel;
long *ability;
long long *ability;
const char *gainstr, *losestr;
}
arc_abil[] = { { 1, &(HStealth), "", "" },
@ -236,11 +236,19 @@ const struct innate {
{ 0, 0, 0, 0 } },
inc_abil[] = { { 1, &(HAntimagic), "", "" },
{ 0, 0, 0, 0 } },
oct_abil[] = { { 1, &(HStone_resistance), "", "" },
{ 1, &(HPoison_resistance), "", "" },
{ 1, &(HStealth), "", "" },
{ 1, &(HSwimming), "", "" },
{ 1, &(HMagical_breathing), "", "" },
{ 1, &(HWaterproof), "", "" },
{ 0, 0, 0, 0 } };
#define next_check u.exerchkturn
STATIC_DCL void NDECL(exerper);
STATIC_DCL void FDECL(postadjabil, (long *));
STATIC_DCL void FDECL(postadjabil, (long long *));
/* adjust an attribute; return TRUE if change is made, FALSE otherwise */
boolean
@ -850,8 +858,7 @@ redist_attr()
STATIC_OVL
void
postadjabil(ability)
long *ability;
postadjabil(long long *ability)
{
if (!ability) return;
if (ability == &(HWarning) || ability == &(HSee_invisible))
@ -936,6 +943,7 @@ int oldlevel, newlevel;
case PM_VAMPIRE: rabil = vam_abil; break;
case PM_HALF_DRAGON: rabil = hlf_abil; break;
case PM_YUKI_ONNA: rabil = yki_abil; break;
case PM_OCTOPODE: rabil = oct_abil; break;
case PM_HUMAN:
case PM_DWARF:
case PM_GNOME:

View file

@ -864,7 +864,7 @@ bc_sanity_check()
onam = simple_typename(otyp);
objects[otyp].oc_name_known = save_nameknown;
}
impossible("uball: type %d (%s), where %d, wornmask=0x%08lx",
impossible("uball: type %d (%s), where %d, wornmask=0x%08llx",
otyp, onam, uball->where, uball->owornmask);
}
/* similar check to ball except can't be in inventory */
@ -883,7 +883,7 @@ bc_sanity_check()
onam = simple_typename(otyp);
objects[otyp].oc_name_known = save_nameknown;
}
impossible("uchain: type %d (%s), where %d, wornmask=0x%08lx",
impossible("uchain: type %d (%s), where %d, wornmask=0x%08llx",
otyp, onam, uchain->where, uchain->owornmask);
}
/* [check bc_order too?] */

View file

@ -184,13 +184,13 @@ NEARDATA struct obj *invent = (struct obj *)0,
*uarmc = (struct obj *)0, *uarmh = (struct obj *)0,
*uarms = (struct obj *)0, *uarmg = (struct obj *)0,
*uarmf = (struct obj *)0, *uamul = (struct obj *)0,
*uright = (struct obj *)0,
*uleft = (struct obj *)0,
*ublindf = (struct obj *)0,
*uchain = (struct obj *)0,
*uball = (struct obj *)0,
*urope = (struct obj *)0;
NEARDATA struct obj *urings[URINGS_SIZE] = {0};
#ifdef TEXTCOLOR
/*
* zap_glyph_color in zap.c assumes that this is in the same order as defined in color.c

View file

@ -10,12 +10,12 @@
#ifndef OVLB
STATIC_DCL long takeoff_mask, taking_off;
STATIC_DCL long long takeoff_mask, taking_off;
#else /* OVLB */
STATIC_OVL NEARDATA long takeoff_mask = 0L;
static NEARDATA long taking_off = 0L;
STATIC_OVL NEARDATA long long takeoff_mask = 0LL;
static NEARDATA long long taking_off = 0LL;
static NEARDATA int todelay;
static boolean cancelled_don = FALSE;
@ -36,14 +36,14 @@ static NEARDATA const char c_armor[] = "armor",
c_sword[] = "sword",
c_axe[] = "axe",
c_that_[] = "that";
static NEARDATA const long takeoff_order[] = { WORN_BLINDF, W_WEP,
WORN_SHIELD, WORN_GLOVES, LEFT_RING, RIGHT_RING, WORN_CLOAK,
WORN_HELMET, WORN_AMUL, WORN_ARMOR,
static NEARDATA const long long takeoff_order[] = { WORN_BLINDF, W_WEP,
WORN_SHIELD, WORN_GLOVES,
W_RING0, W_RING1, W_RING2, W_RING3, W_RING4, W_RING5, W_RING6, W_RING7,
WORN_CLOAK, WORN_HELMET, WORN_AMUL, WORN_ARMOR,
#ifdef TOURIST
WORN_SHIRT,
#endif
WORN_BOOTS, W_SWAPWEP, W_QUIVER, 0L };
WORN_BOOTS, W_SWAPWEP, W_QUIVER, 0LL };
STATIC_DCL void FDECL(on_msg, (struct obj *));
STATIC_DCL int NDECL(Cloak_on);
@ -1457,7 +1457,7 @@ donning(otmp) /* also checks for doffing */
register struct obj *otmp;
{
/* long what = (occupation == take_off) ? taking_off : 0L; */
long what = taking_off; /* if nonzero, occupation is implied */
long long what = taking_off; /* if nonzero, occupation is implied */
boolean result = FALSE;
if (otmp == uarm)
@ -1551,7 +1551,7 @@ dotakeoff()
"dragon scale mail is");
else
pline("Not wearing any armor.%s", (iflags.cmdassist &&
(uleft || uright || uamul || ublindf)) ?
(count_worn_rings(FALSE) || uamul || ublindf)) ?
" Use 'R' command to remove accessories." : "");
return MOVE_CANCELLED;
}
@ -1597,8 +1597,9 @@ doremring()
}
#define MOREACC(x) if (x) { Accessories++; otmp = x; }
MOREACC(uleft);
MOREACC(uright);
for (int i = 0; i < URINGS_SIZE; i++) {
MOREACC(urings[i]);
}
MOREACC(uamul);
MOREACC(ublindf);
@ -1625,7 +1626,7 @@ doremring()
if (!takeoff_mask) return MOVE_CANCELLED;
reset_remarm(); /* not used by Ring_/Amulet_/Blindf_off() */
if (otmp == uright || otmp == uleft) {
if (otmp->owornmask & W_RING) {
/* Sometimes we want to give the off_msg before removing and
* sometimes after; for instance, "you were wearing a moonstone
* ring (on right hand)" is desired but "you were wearing a
@ -1737,7 +1738,7 @@ register struct obj *otmp;
else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
off_msg(otmp);
}
takeoff_mask = taking_off = 0L;
takeoff_mask = taking_off = 0LL;
return MOVE_STANDARD;
}
@ -1765,7 +1766,7 @@ const char *cc1, *cc2;
int
canwearobj(otmp,mask,noisy)
struct obj *otmp;
long *mask;
long long *mask;
boolean noisy;
{
int err = 0;
@ -1963,7 +1964,7 @@ dowear()
{
struct obj *otmp;
int delay;
long mask = 0;
long long mask = 0;
if (nohands(youracedata)) {
pline("Don't even bother.");
@ -2025,7 +2026,7 @@ dowear()
else if(otmp == uarm) (void) Armor_on();
on_msg(otmp);
}
takeoff_mask = taking_off = 0L;
takeoff_mask = taking_off = 0LL;
return MOVE_STANDARD;
}
@ -2033,14 +2034,20 @@ int
doputon()
{
register struct obj *otmp;
long mask = 0L;
long long mask = 0LL;
if(!freehand()){
You("have no free %s to put on accessories with!", body_part(HAND));
return MOVE_CANCELLED;
}
if(uleft && (uright || (uarmg && uarmg->oartifact == ART_CLAWS_OF_THE_REVENANCER)) && uamul && ublindf) {
int free_ring_slots = (youracedata->mtyp == PM_OCTOPODE ? 8 : 2) - count_worn_rings(TRUE);
if (free_ring_slots < 0) {
impossible("doputon: more worn rings than ring slots?");
free_ring_slots = 0;
}
if(!free_ring_slots && uamul && ublindf) {
Your("%s%s are full, and you're already wearing an amulet and %s.",
humanoid(youracedata) ? "ring-" : "",
makeplural(body_part(FINGER)),
@ -2070,34 +2077,64 @@ doputon()
You("cannot make the ring stick to your body.");
return MOVE_CANCELLED;
}
if(uleft && (uright || (uarmg && uarmg->oartifact == ART_CLAWS_OF_THE_REVENANCER))){
if(!free_ring_slots){
There("are no more %s%s to fill.",
humanoid(youracedata) ? "ring-" : "",
makeplural(body_part(FINGER)));
return MOVE_CANCELLED;
}
if(uleft) mask = RIGHT_RING;
else if((uright || (uarmg && uarmg->oartifact == ART_CLAWS_OF_THE_REVENANCER))) mask = LEFT_RING;
else do {
if(youracedata->mtyp == PM_OCTOPODE) do {
char qbuf[QBUFSZ];
char answer;
Sprintf(qbuf, "Which %s%s, Right or Left?",
char respchars[8] = {0};
for (int i = 0; i < 8; i++)
if (!urings[i])
Sprintf(eos(respchars), "%d", i+1);
Sprintf(qbuf, "Which %s%s?",
humanoid(youracedata) ? "ring-" : "",
body_part(FINGER));
if(!(answer = yn_function(qbuf, "rl", '\0')))
/* Don't ask if only one slot is free. */
if(strlen(respchars) == 1)
answer = respchars[0];
else if(!(answer = yn_function(qbuf, respchars, '\0')))
return MOVE_CANCELLED;
switch(answer){
case 'l':
case 'L':
mask = LEFT_RING;
break;
case 'r':
case 'R':
mask = RIGHT_RING;
break;
case '1': mask = W_RING0; break;
case '2': mask = W_RING1; break;
case '3': mask = W_RING2; break;
case '4': mask = W_RING3; break;
case '5': mask = W_RING4; break;
case '6': mask = W_RING5; break;
case '7': mask = W_RING6; break;
case '8': mask = W_RING7; break;
}
} while(!mask);
} while(!mask); else {
if(uleft) mask = RIGHT_RING;
else if((uright || (uarmg && uarmg->oartifact == ART_CLAWS_OF_THE_REVENANCER))) mask = LEFT_RING;
else do {
char qbuf[QBUFSZ];
char answer;
Sprintf(qbuf, "Which %s%s, Right or Left?",
humanoid(youracedata) ? "ring-" : "",
body_part(FINGER));
if(!(answer = yn_function(qbuf, "rl", '\0')))
return MOVE_CANCELLED;
switch(answer){
case 'l':
case 'L':
mask = LEFT_RING;
break;
case 'r':
case 'R':
mask = RIGHT_RING;
break;
}
} while(!mask);
}
if (uarmg && uarmg->cursed && !Weldproof) {
uarmg->bknown = TRUE;
You("cannot remove your gloves to put on the ring.");
@ -2626,11 +2663,13 @@ base_uac()
}
}
}
if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
for (int i = 0; i < URINGS_SIZE; i++)
if (urings[i] && urings[i]->otyp == RIN_PROTECTION)
uac -= urings[i]->spe;
if (HProtection & INTRINSIC) uac -= (u.ublessed+1)/2;
if(Race_if(PM_ETHEREALOID)) uac -= u.ulevel;
if(Race_if(PM_SNOW_CLOUD) && !Upolyd) uac -= u.ulevel;
if(Race_if(PM_SNOW_CLOUD) && !Upolyd) uac -= u.ulevel;
if(Race_if(PM_OCTOPODE)) uac -= u.ulevel/2;
if(u.utats & TAT_BULWARK) uac -= 1;
uac -= u.uacinc;
uac -= u.spiritAC;
@ -2790,7 +2829,7 @@ int base_nat_udr()
{
int udr = 0;
if(Race_if(PM_ORC)){
if(Race_if(PM_ORC) || Race_if(PM_OCTOPODE)){
udr += u.ulevel/10;
}
if(is_ent_species(youracedata, ENT_MIMOSA)) udr++;
@ -2798,7 +2837,7 @@ int base_nat_udr()
if(Race_if(PM_SNOW_CLOUD) && !Upolyd)
udr += (u.ulevel/6)+1;
if(Race_if(PM_HALF_DRAGON)){
//DS half dragons may be more humanoid
if(Humanoid_half_dragon(urole.malenum)){
@ -3095,6 +3134,10 @@ glibr()
boolean leftfall, rightfall;
const char *otherwep = 0;
/* octopodes' suckers make them immune to glib */
if(youracedata->mtyp == PM_OCTOPODE)
return;
leftfall = (uleft && !uleft->cursed && !Weldproof &&
(!uwep || !welded(uwep) || !bimanual(uwep,youracedata)));
rightfall = (uright && !uright->cursed && !Weldproof && (!welded(uwep)));
@ -3374,15 +3417,22 @@ register struct obj *otmp;
#ifdef TOURIST
else if(otmp == uarmu) takeoff_mask |= WORN_SHIRT;
#endif
else if(otmp == uleft) takeoff_mask |= LEFT_RING;
else if(otmp == uright) takeoff_mask |= RIGHT_RING;
else if(otmp == uamul) takeoff_mask |= WORN_AMUL;
else if(otmp == ublindf) takeoff_mask |= WORN_BLINDF;
else if(otmp == uwep) takeoff_mask |= W_WEP;
else if(otmp == uswapwep) takeoff_mask |= W_SWAPWEP;
else if(otmp == uquiver) takeoff_mask |= W_QUIVER;
else impossible("select_off: %s???", doname(otmp));
else {
boolean found_ring = FALSE;
for (int i = 0; i < URINGS_SIZE; i++) {
if (otmp == urings[i]) {
found_ring = TRUE;
takeoff_mask |= ring_index_to_wornmask[i];
break;
}
}
if (!found_ring) impossible("select_off: %s???", doname(otmp));
}
return MOVE_CANCELLED;
}
@ -3433,15 +3483,20 @@ do_takeoff()
} else if (taking_off == WORN_AMUL) {
otmp = uamul;
if(!cursed(otmp)) Amulet_off();
} else if (taking_off == LEFT_RING) {
otmp = uleft;
if(!cursed(otmp)) Ring_off(uleft);
} else if (taking_off == RIGHT_RING) {
otmp = uright;
if(!cursed(otmp)) Ring_off(uright);
} else if (taking_off == WORN_BLINDF) {
if (!cursed(ublindf)) Blindf_off(ublindf);
} else impossible("do_takeoff: taking off %lx", taking_off);
} else {
boolean found_ring = FALSE;
for (int i = 0; i < URINGS_SIZE; i++) {
if (taking_off & ring_index_to_wornmask[i]) {
found_ring = TRUE;
otmp = urings[i];
if(!cursed(otmp)) Ring_off(urings[i]);
break;
}
}
if (!found_ring) impossible("do_takeoff: taking off %llx", taking_off);
}
return(otmp);
}
@ -3463,7 +3518,7 @@ take_off()
if ((otmp = do_takeoff())) off_msg(otmp);
}
takeoff_mask &= ~taking_off;
taking_off = 0L;
taking_off = 0LL;
}
for(i = 0; takeoff_order[i]; i++)
@ -3475,7 +3530,7 @@ take_off()
otmp = (struct obj *) 0;
todelay = 0;
if (taking_off == 0L) {
if (taking_off == 0LL) {
You("finish %s.", disrobing);
return MOVE_FINISHED_OCCUPATION;
} else if (taking_off == W_WEP) {
@ -3510,14 +3565,12 @@ take_off()
#endif
} else if (taking_off == WORN_AMUL) {
todelay = 1;
} else if (taking_off == LEFT_RING) {
todelay = 1;
} else if (taking_off == RIGHT_RING) {
} else if (taking_off & W_RING) {
todelay = 1;
} else if (taking_off == WORN_BLINDF) {
todelay = 2;
} else {
impossible("take_off: taking off %lx", taking_off);
impossible("take_off: taking off %llx", taking_off);
return MOVE_FINISHED_OCCUPATION; /* force done */
}
@ -3537,7 +3590,7 @@ take_off()
void
reset_remarm()
{
taking_off = takeoff_mask = 0L;
taking_off = takeoff_mask = 0LL;
disrobing = nul;
}
@ -3744,7 +3797,7 @@ register struct obj *otmp;
if (mtmp == &youmonst)
return destroy_arm(otmp);
long unwornmask;
long long unwornmask;
if(!otmp || !mtmp)
return 0;
if(obj_resists(otmp, 0, 100))
@ -3752,7 +3805,7 @@ register struct obj *otmp;
if(!otmp->owornmask)
return 0;
obj_extract_self(otmp);
if ((unwornmask = otmp->owornmask) != 0L) {
if ((unwornmask = otmp->owornmask) != 0LL) {
mtmp->misc_worn_check &= ~unwornmask;
if (otmp->owornmask & W_WEP){
setmnotwielded(mtmp,otmp);
@ -3762,7 +3815,7 @@ register struct obj *otmp;
setmnotwielded(mtmp,otmp);
MON_NOSWEP(mtmp);
}
otmp->owornmask = 0L;
otmp->owornmask = 0LL;
update_mon_intrinsics(mtmp, otmp, FALSE, FALSE);
if(unwornmask&W_ARM){
if(canseemon(mtmp))
@ -3890,7 +3943,7 @@ register struct obj *otmp;
if (mtmp == &youmonst)
return claws_destroy_arm(otmp);
long unwornmask;
long long unwornmask;
if(!otmp || !mtmp)
return 0;
if(obj_resists(otmp, 0, 100))
@ -3898,7 +3951,7 @@ register struct obj *otmp;
if(!otmp->owornmask)
return 0;
obj_extract_self(otmp);
if ((unwornmask = otmp->owornmask) != 0L) {
if ((unwornmask = otmp->owornmask) != 0LL) {
mtmp->misc_worn_check &= ~unwornmask;
if (otmp->owornmask & W_WEP){
setmnotwielded(mtmp,otmp);
@ -3908,7 +3961,7 @@ register struct obj *otmp;
setmnotwielded(mtmp,otmp);
MON_NOSWEP(mtmp);
}
otmp->owornmask = 0L;
otmp->owornmask = 0LL;
update_mon_intrinsics(mtmp, otmp, FALSE, FALSE);
if(unwornmask&W_ARM){
if(canseemon(mtmp))

View file

@ -2197,7 +2197,7 @@ struct obj *otmp;
/* Note: rings are not so common that this is unbalancing. */
/* (How often do you even _find_ 3 rings of polymorph in a game?) */
oldprop = u.uprops[objects[typ].oc_oprop[0]].intrinsic;
if (otmp == uleft || otmp == uright) {
if (otmp->owornmask & W_RING) {
Ring_gone(otmp);
if (u.uhp <= 0) return; /* died from sink fall */
}
@ -4092,24 +4092,30 @@ gethungry() /* as time goes by - called by moveloop() and domove() */
/* Conflict uses up food too */
if (HConflict || (EConflict & (~W_ARTI))) (Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--);
/* Alacrity uses up food too */
if (EFast & (W_RINGL|W_RINGR)) (Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--);
if (EFast & W_RING) (Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--);
/* +0 charged rings don't do anything, so don't affect hunger */
/* Slow digestion still uses ring hunger */
#define RING_HUNGER(ring) \
if (ring && \
(ring->spe || !objects[ring->otyp].oc_charged)) \
(Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--)
/* TODO clean this up */
switch ((int)(moves % 20)) { /* note: use even cases only */
case 4: if (uleft &&
(uleft->spe || !objects[uleft->otyp].oc_charged))
(Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--);
break;
case 2: RING_HUNGER(urings[2]); break;
case 4: RING_HUNGER(uleft); break;
case 6: RING_HUNGER(urings[3]); break;
case 8: if (uamul) (Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--);
break;
case 12: if (uright &&
(uright->spe || !objects[uright->otyp].oc_charged))
(Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--);
break;
case 10: RING_HUNGER(urings[4]); break;
case 12: RING_HUNGER(uright); break;
case 14: RING_HUNGER(urings[5]); break;
case 16: if (u.uhave.amulet) (Race_if(PM_INCANTIFIER) ? u.uen-- : u.uhunger--);
break;
case 18: RING_HUNGER(urings[6]); break;
case 20: RING_HUNGER(urings[7]); break;
default: break;
}
#undef RING_HUNGER
}
newuhs(TRUE);
}

View file

@ -885,6 +885,15 @@ Check_twin_lifesaving()
return FALSE;
}
boolean
Check_ring_lifesaving()
{
struct obj *ring = uring_otyp(RIN_WISHES);
if (ring && ring->spe > 0)
return TRUE;
return FALSE;
}
STATIC_OVL void
Use_crystal_lifesaving()
{
@ -1070,6 +1079,7 @@ int how;
if (how < PANICKED) u.umortality++;
if (Lifesaved && (how <= GENOCIDED)) {
int ring_index; /* used for checking ring lifesaving */
pline("But wait...");
if(uarmh && uarmh->oartifact == ART_HELM_OF_UNDEATH) {
otmp = uarmh;
@ -1167,24 +1177,20 @@ int how;
lsvd = LSVD_MISC;
pline("Time unwinds and twists!");
Use_crystal_lifesaving();
} else if(uleft && uleft->otyp == RIN_WISHES && uleft->spe > 0){
} else if(((ring_index = uring_otyp_index(RIN_WISHES)) != -1) && urings[ring_index]->spe > 0){
struct obj *obj = urings[ring_index];
char which[BUFSZ];
nth_ring_text(ring_index, which, BUFSZ);
lsvd = LSVD_MISC;
You("wish that hadn't happened.");
pline("A star flares on your left ring-finger!");
uleft->spe--;
} else if(uright && uright->otyp == RIN_WISHES && uright->spe > 0){
lsvd = LSVD_MISC;
You("wish that hadn't happened.");
pline("A star flares on your right ring-finger!");
uright->spe--;
pline("A star flares on your %s %s%s!", which,
humanoid(youracedata) ? "ring-" : "",
body_part(FINGER));
obj->spe--;
} else if(check_mutation(ABHORRENT_SPORE) && !(mvitals[PM_DARK_YOUNG].mvflags & G_GENOD)){
lsvd = LSVD_SPOR;
if (how == DISINTEGRATED) pline("Your dust is consumed by the abhorrent spore!");
else pline("Your body melts and is consumed by the abhorrent spore!");
if (Upolyd && uskin && uskin->oartifact == ART_MIRRORED_MASK) {
pline("Your mask falls to pieces!");
useup(uskin);
}
if(youracedata->mtyp == PM_DARK_YOUNG)
change_gevurah(16); //cheated death extra.

View file

@ -938,9 +938,9 @@ boolean dumping;
#endif
if (Adornment) {
int adorn = 0;
if(uleft && uleft->otyp == RIN_ADORNMENT) adorn += uleft->spe;
if(uright && uright->otyp == RIN_ADORNMENT) adorn += uright->spe;
for (int i = 0; i < URINGS_SIZE; i++)
if (urings[i] && urings[i]->otyp == RIN_ADORNMENT)
adorn += urings[i]->spe;
if (adorn < 0)
you_are("poorly adorned");
else
@ -1048,8 +1048,9 @@ boolean dumping;
if (u.uspellprot || Protection || u.uuur/2 || u.uuur_duration || (u.uvaul+4)/5) {
int prot = 0;
if(uleft && uleft->otyp == RIN_PROTECTION) prot += uleft->spe;
if(uright && uright->otyp == RIN_PROTECTION) prot += uright->spe;
for (int i = 0; i < URINGS_SIZE; i++)
if (urings[i] && urings[i]->otyp == RIN_PROTECTION)
prot += urings[i]->spe;
if (HProtection & INTRINSIC) prot += u.ublessed;
prot += u.uspellprot;
prot += u.uuur/2;
@ -1247,6 +1248,10 @@ resistances_enlightenment()
putstr(en_win, 0, "Your greased cloak protects your gear.");
else if (u.sealsActive&SEAL_ENKI)
putstr(en_win, 0, "YOU'RE soaked, but the water doesn't wet your gear.");
else if (Race_if(PM_HALF_DRAGON) && u.ulevel >= 15 && flags.HDbreath == AD_COLD)
putstr(en_win, 0, "Your scales protect you from the water around you.");
else if (Race_if(PM_OCTOPODE))
putstr(en_win, 0, "Your waterproof field protects you from the water around you.");
else
putstr(en_win, 0, "Your equipment protects you from the water around you.");
}

View file

@ -527,15 +527,9 @@ dosinkfall()
ELevitation &= ~W_ARTI;
HLevitation &= ~(I_SPECIAL|TIMEOUT);
HLevitation++;
if(uleft && uleft->otyp == RIN_LEVITATION) {
obj = uleft;
Ring_off(obj);
off_msg(obj);
}
if(uright && uright->otyp == RIN_LEVITATION) {
obj = uright;
Ring_off(obj);
off_msg(obj);
if ((obj = uring_otyp(RIN_LEVITATION))) {
Ring_off(obj);
off_msg(obj);
}
if(uarmf && uarmf->otyp == FLYING_BOOTS) {
obj = uarmf;
@ -1643,7 +1637,7 @@ domove()
boolean ww_boots = (uarmf && uarmf->otyp == WATER_WALKING_BOOTS && objects[WATER_WALKING_BOOTS].oc_name_known);
boolean visible_ww = ww_boots || u.sealsActive&SEAL_EURYNOME || HWwalking ||
(u.uprops[WWALKING].extrinsic & W_ARTI) || (u.uprops[WWALKING].extrinsic & W_ART) ||
(uleft && uleft->oartifact == ART_NENYA) || (uright && uright->oartifact == ART_NENYA);
uring_art(ART_NENYA);
/* Going into 3D water with limited breath can be dangerous. */
boolean safe_3dwater = safe_inwater && Breathless;

View file

@ -1120,7 +1120,7 @@ register const char *let,*word;
xchar foox = 0;
long cnt;
boolean prezero = FALSE;
long dummymask;
long long dummymask;
if(nextgetobj) return getnextgetobj();
@ -6345,8 +6345,7 @@ u_clothing_discomfort()
if(uamul){
count++;
}
if(uleft) count++;
if(uright) count++;
count += count_worn_rings(FALSE);
if(ublindf){
count++;
if(ublindf->otyp == BLINDFOLD
@ -6508,10 +6507,9 @@ int material;
count++;
if(uarmf && uarmf->obj_material == material)
count++;
if(uleft && uleft->obj_material == material)
count++;
if(uright && uright->obj_material == material)
count++;
for (int i = 0; i < URINGS_SIZE; i++)
if (urings[i] && urings[i]->obj_material == material)
count++;
if(uamul && uamul->obj_material == material && !uarmu && !(uarm && arm_blocks_upper_body(uarm->otyp)))
count++;
if(u.uentangled_oid && !uarmu && !uarm && !(uarm && arm_blocks_upper_body(uarm->otyp)) && entangle_material(&youmonst, material))

View file

@ -6895,9 +6895,10 @@ int tary;
/* don't cast red word if target is already disrobed/disrobing */
if (spellnum == MON_RED_WORD
&& (youdef ?
(u.ufirst_know || !(uarmh || uarmc || uarm || uarmu || uarmg || uarmf || uamul || ublindf || uleft || uright))
: (!(mdef->misc_worn_check&(W_ARMOR|W_AMUL|W_TOOL)) || mdef->mdisrobe)
)
(u.ufirst_know || !(uarmh || uarmc || uarm || uarmu || uarmg || uarmf
|| uamul || ublindf || count_worn_rings(FALSE)))
: (!(mdef->misc_worn_check&(W_ARMOR|W_AMUL|W_TOOL)) || mdef->mdisrobe)
)
)
return TRUE;
/* peaceful monsters won't cast invisibility if you can't see invisible,

View file

@ -7559,6 +7559,14 @@ is a red right hand
/*
* sea monsters
*/
MON("octopode", S_EEL,//
LVL(0, 12, 0, 0), G_NOGEN,
DEF(NAT_AC(0)),
A(ATTK(AT_WEAP, AD_PHYS, 1, 8), ATTK(AT_TENT, AD_WRAP, 1, 8)),
SIZ(WT_MEDIUM, CN_MEDIUM, MS_HUMANOID, MZ_MEDIUM), MR_STONE|MR_POISON, 0,
MM_BREATHLESS|MM_SWIM|MM_AMPHIBIOUS /*MM*/, MT_OMNIVORE|MT_COLLECT /*MT*/, MF_MARTIAL_B /*MF*/,
MB_LONGHEAD|MB_CAN_AMULET|MB_THICK_HIDE|MB_NOGLOVES|MB_STRONG /*MB*/, MG_NOWISH|MG_INFRAVISIBLE /*MG*/,
MA_AQUATIC /*MA*/, MV_LOWLIGHT2 /*MV*/, 0 /*MW*/, HI_DOMESTIC),
MON("illithid larva", S_EEL,//5
LVL(3, 3, 0, 1), (G_NOGEN|0),
DEF(NAT_AC(10-6)),

View file

@ -299,6 +299,26 @@ struct obj *otmp;
}
int
nth_ring_text(int ring_index, char *buf, size_t bufsize)
{
if (youracedata->mtyp != PM_OCTOPODE && ring_index <= 1)
return snprintf(buf, bufsize, ring_index == 0 ? "left" : "right");
else {
switch (ring_index+1) {
case 1: return snprintf(buf, bufsize, "first");
case 2: return snprintf(buf, bufsize, "second");
case 3: return snprintf(buf, bufsize, "third");
case 4: return snprintf(buf, bufsize, "fourth");
case 5: return snprintf(buf, bufsize, "fifth");
case 6: return snprintf(buf, bufsize, "sixth");
case 7: return snprintf(buf, bufsize, "seventh");
case 8: return snprintf(buf, bufsize, "eighth");
default: return snprintf(buf, bufsize, "%dth", ring_index+1);
}
}
}
const char *
lightsaber_colorText(otmp)
struct obj *otmp;
@ -2413,10 +2433,20 @@ weapon:
ring:
if (obj->otyp == RIN_WISHES && obj->known) Sprintf(eos(buf), " (%d remaining)", obj->spe);
if (obj->otyp == RIN_WISHES && !obj->known && obj->spe > 0) Sprintf(eos(buf), " with %d star%s", obj->spe, plur(obj->spe));
if (obj->owornmask & W_RINGR) Strcat(buf, " (on right ");
if (obj->owornmask & W_RINGL) Strcat(buf, " (on left ");
for (int i = 0; i < URINGS_SIZE; i++) {
if (obj->owornmask & ring_index_to_wornmask[i]) {
char tmpbuf[BUFSZ];
nth_ring_text(i, tmpbuf, BUFSZ);
Sprintf(eos(buf), " (on %s ", tmpbuf);
}
}
if (obj->owornmask & W_RING) {
const char *hand_s = obj->where == OBJ_MINVENT ? mbodypart(obj->ocarry, HAND) : body_part(HAND);
const char *hand_s = obj->where == OBJ_MINVENT
? mbodypart(obj->ocarry, HAND)
/* body_part(HAND) is "tentacle pair" for octopodes */
: (youracedata->mtyp == PM_OCTOPODE
? "tentacle"
: body_part(HAND));
Strcat(buf, hand_s);
if (isSignetRing(obj->otyp)){
if (obj->opoisoned & OPOISON_BASIC) Strcat(buf, ", poison injecting");

View file

@ -802,6 +802,18 @@ break_armor()
dropx(otmp);
}
}
if (youracedata->mtyp != PM_OCTOPODE) {
boolean messaged = FALSE;
for (int i = 2; i < URINGS_SIZE; i++) {
if (urings[i]) {
if (!messaged) {
You("can no longer wear eight rings!");
messaged = TRUE;
}
Ring_off(urings[i]);
}
}
}
}
void
@ -2356,6 +2368,15 @@ int part;
"lung", "nose", "stomach", "heart",
"skin", "flesh", "beat", "bones",
"ear", "ears", "tongue", "brain",
"creak", "crack" },
*octopode_parts[] = {
"arm", "eye", "face", "tentacle",
"tentacle tip", "rear tentacle", "tentacle pair", "tentacled",
"head", "rear tentacle tip", "light headed", "neck",
"length", "tentacle tip", "surface", "blood",
"gill", "rhinophore", "stomach", "heart",
"skin", "flesh", "beat", "shell",
"statocyst", "statocysts", "radula", "brain",
"creak", "crack" };
/* claw attacks are overloaded in mons[]; most humanoids with
such attacks should still reference hands rather than claws */
@ -2451,6 +2472,8 @@ int part;
return uvuudaum_parts[part];
if (mptr->mtyp == PM_DRACAE_ELADRIN)
return dracae_parts[part];
if (mptr->mtyp == PM_OCTOPODE)
return octopode_parts[part];
//S-based part lists
if (mptr->mlet == S_PLANT)

View file

@ -46,8 +46,7 @@ long incr;
/* set the timeout field of intrinsic `which' */
void
set_itimeout(which, val)
long *which, val;
set_itimeout(long long *which, long val)
{
*which &= ~TIMEOUT;
*which |= itimeout(val);
@ -55,9 +54,7 @@ long *which, val;
/* increment the timeout field of intrinsic `which' */
void
incr_itimeout(which, incr)
long *which;
long incr;
incr_itimeout(long long *which, long incr)
{
set_itimeout(which, itimeout_incr(*which, incr));
}

View file

@ -1244,38 +1244,34 @@ int curse_bless;
objects[obj->otyp].oc_charged && obj->otyp != RIN_WISHES) {
/* charging does not affect ring's curse/bless status */
int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
boolean is_on = (obj == uleft || obj == uright);
long long ringmask = obj->owornmask & W_RING;
/* destruction depends on current state, not adjustment */
if (obj->spe > (6-rnl(7)) || obj->spe <= -5) {
if(!obj->oartifact){
Your("%s %s momentarily, then %s!",
xname(obj), otense(obj,"pulsate"), otense(obj,"explode"));
if (is_on) Ring_gone(obj);
if (ringmask) Ring_gone(obj);
s = rnd(3 * abs(obj->spe)); /* amount of damage */
useup(obj);
losehp(s, "exploding ring", KILLED_BY_AN);
return 1;
} 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);
if (ringmask) Ring_off(obj);
obj->spe = 0; /* update the ring while it's off */
if (is_on) setworn(obj, mask), Ring_on(obj);
if (ringmask) setworn(obj, ringmask), 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 */
if (is_on) Ring_off(obj);
if (ringmask) Ring_off(obj);
obj->spe += s; /* update the ring while it's off */
if (is_on) setworn(obj, mask), Ring_on(obj);
if (ringmask) setworn(obj, ringmask), Ring_on(obj);
/* oartifact: if a touch-sensitive artifact ring is
ever created the above will need to be revised */
}
@ -1893,7 +1889,7 @@ struct obj *sobj;
otmp->known = 1;
fix_object(otmp);
long wornmask = 0L;
long long wornmask = 0LL;
if (is_worn && canwearobj(otmp, &wornmask, FALSE)) {
setworn(otmp, wornmask);
}
@ -2002,7 +1998,7 @@ struct obj *sobj;
otmp->blessed = 1;
}
otmp->known = 1;
long wornmask = 0L;
long long wornmask = 0LL;
if (is_worn && canwearobj(otmp, &wornmask, FALSE)) {
setworn(otmp, W_ARM);
}

View file

@ -118,7 +118,7 @@ struct Role roles[] = {
PM_STRANGE_CORPSE, PM_PEASANT, PM_ACERERAK,
PM_SKELETON, PM_LICH, S_HUMAN, S_HUMANOID,
ART_PEN_OF_THE_VOID,
MA_HUMAN|MA_DWARF|MA_GNOME|MA_ELF|MA_ORC|MA_CLOCK|MA_VAMPIRE|MA_DRAGON|MA_ANIMAL|MA_FEY|MA_REPTILIAN|MA_ETHEREAL|MA_PLANT, ROLE_MALE|ROLE_FEMALE |
MA_HUMAN|MA_DWARF|MA_GNOME|MA_ELF|MA_ORC|MA_CLOCK|MA_VAMPIRE|MA_DRAGON|MA_ANIMAL|MA_FEY|MA_REPTILIAN|MA_ETHEREAL|MA_PLANT|MA_AQUATIC, ROLE_MALE|ROLE_FEMALE |
ROLE_LAWFUL|ROLE_CHAOTIC|ROLE_NEUTRAL,
/* Str Int Wis Dex Con Cha */
{ 6, 6, 6, 6, 6, 6 },
@ -224,7 +224,7 @@ struct Role roles[] = {
PM_ULITHARID, PM_MINDLESS_THRALL, PM_MENZOBERRANZAN,
NON_PM, NON_PM, NON_PM, NON_PM,
ART_ELDER_CEREBRAL_FLUID,
MA_HUMAN|MA_DWARF|MA_GNOME|MA_ELF|MA_ORC|MA_DRAGON|MA_ANIMAL|MA_REPTILIAN|MA_PLANT|MA_FEY|MA_CLOCK, ROLE_MALE|ROLE_FEMALE |
MA_HUMAN|MA_DWARF|MA_GNOME|MA_ELF|MA_ORC|MA_DRAGON|MA_ANIMAL|MA_REPTILIAN|MA_PLANT|MA_FEY|MA_CLOCK|MA_AQUATIC, ROLE_MALE|ROLE_FEMALE |
ROLE_LAWFUL,
/* Str Int Wis Dex Con Cha */
{ 12, 10, 7, 12, 12, 7 },
@ -384,7 +384,7 @@ struct Role roles[] = {
PM_MAYOR_CUMMERBUND, PM_PIRATE_BROTHER, PM_BLACKBEARD_S_GHOST,
PM_SKELETAL_PIRATE, PM_SOLDIER, S_RODENT, S_ELEMENTAL, /* Ghost pirates, soldiers, rats in the food stores, and the occasional storm*/
ART_TREASURY_OF_PROTEUS,
MA_HUMAN|MA_ELF, ROLE_MALE|ROLE_FEMALE |
MA_HUMAN|MA_ELF|MA_AQUATIC, ROLE_MALE|ROLE_FEMALE |
ROLE_CHAOTIC|ROLE_NEUTRAL,
/* Str Int Wis Dex Con Cha */
{ 10, 7, 7, 10, 10, 7 },
@ -412,7 +412,7 @@ struct Role roles[] = {
PM_MASTER_OF_THIEVES, PM_THUG, PM_MASTER_ASSASSIN,
PM_LEPRECHAUN, PM_GUARDIAN_NAGA, S_NYMPH, S_NAGA,
ART_MASTER_KEY_OF_THIEVERY,
MA_HUMAN|MA_ORC|MA_VAMPIRE|MA_ELF|MA_DRAGON|MA_ANIMAL|MA_REPTILIAN, ROLE_MALE|ROLE_FEMALE |
MA_HUMAN|MA_ORC|MA_VAMPIRE|MA_ELF|MA_DRAGON|MA_ANIMAL|MA_REPTILIAN|MA_AQUATIC, ROLE_MALE|ROLE_FEMALE |
ROLE_CHAOTIC,
/* Str Int Wis Dex Con Cha */
{ 7, 7, 7, 10, 7, 6 },
@ -569,7 +569,7 @@ struct Role roles[] = {
PM_NEFERET_THE_GREEN, PM_APPRENTICE, PM_DARK_ONE,
PM_VAMPIRE_BAT, PM_XORN, S_BAT, S_WRAITH,
ART_EYE_OF_THE_AETHIOPICA,
MA_HUMAN|MA_ELF|MA_GNOME|MA_ORC|MA_VAMPIRE|MA_DRAGON|MA_REPTILIAN|MA_ETHEREAL|MA_PLANT, ROLE_MALE|ROLE_FEMALE |
MA_HUMAN|MA_ELF|MA_GNOME|MA_ORC|MA_VAMPIRE|MA_DRAGON|MA_REPTILIAN|MA_ETHEREAL|MA_PLANT|MA_AQUATIC, ROLE_MALE|ROLE_FEMALE |
ROLE_NEUTRAL|ROLE_CHAOTIC,
/* Str Int Wis Dex Con Cha */
{ 7, 10, 7, 7, 7, 7 },
@ -929,6 +929,21 @@ const struct Race races[] = {
NORMALNIGHTVIS,
SPE_CHARM_MONSTER, -15
},
{ "Octopode", "octopodic", "octopode-kind", "Oct",
{0, 0},
PM_OCTOPODE, NON_PM, PM_HUMAN_MUMMY, PM_OCTOPODE,
ROLE_MALE|ROLE_FEMALE |
ROLE_LAWFUL|ROLE_NEUTRAL|ROLE_CHAOTIC,
MA_AQUATIC, 0, 0,
/* Str Int Wis Dex Con Cha */
{ 3, 3, 3, 3, 3, 3 },
{ STR18(100), 20, 18, 20, 16, 16 },
/* Init Lower Higher */
{ 2, 0, 0, 2, 1, 0 }, /* Hit points */
{ 1, 0, 2, 0, 2, 0 }, /* Energy */
NIGHTVISION2,
SPE_POISON_SPRAY, -15
},
/* Array terminator */
{ 0, 0, 0, 0, 0 }};

View file

@ -42,8 +42,7 @@ struct attack *mattk;
if(youdef || youagr){
if(Chastity) return 0;
if ((uleft && uleft->otyp == find_engagement_ring()) ||
(uright && uright->otyp == find_engagement_ring()))
if (uring_otyp(find_engagement_ring()))
return 0;
}
@ -1298,14 +1297,15 @@ struct monst * mon;
xname(ring));
}
makeknown(RIN_ADORNMENT);
if (ring == uleft || ring == uright) Ring_gone(ring);
if (ring->owornmask & W_RING) Ring_gone(ring);
if (ring == uwep) setuwep((struct obj *)0);
if (ring == uswapwep) setuswapwep((struct obj *)0);
if (ring == uquiver) setuqwep((struct obj *)0);
freeinv(ring);
(void)mpickobj(mon, ring);
}
else {
/* TODO implement this for octopodes (>2 ring slots) */
else if (youracedata->mtyp != PM_OCTOPODE) {
if (uleft && uright && uleft->otyp == RIN_ADORNMENT
&& (uright->otyp == RIN_ADORNMENT || (uarmg && uarmg->oartifact == ART_CLAWS_OF_THE_REVENANCER)))
break;

View file

@ -5597,7 +5597,7 @@ shk_armor_works(slang, shkp)
obj->otyp - GRAY_DRAGON_SCALES;
obj->cursed = 0;
obj->known = 1;
long wornmask = 0L;
long long wornmask = 0LL;
if (is_worn && canwearobj(obj, &wornmask, FALSE)) {
setworn(obj, wornmask);
}

View file

@ -82,7 +82,7 @@ unsigned gpflags;
((Swimming || Amphibious) && Waterproof && !(u.sealsActive&SEAL_OSE)));
else return (mon_resistance(mtmp,FLYING) || breathless_mon(mtmp) || mon_resistance(mtmp,SWIMMING) ||
is_clinger(mdat) || amphibious_mon(mtmp));
} else if (mdat->mlet == S_EEL && !ignorewater && rn2(13)) {
} else if (mdat->mlet == S_EEL && mdat->mtyp != PM_OCTOPODE && !ignorewater && rn2(13)) {
if (is_pool(x, y, TRUE))
return (mdat->msize == MZ_TINY);
return FALSE;

View file

@ -17,7 +17,7 @@ STATIC_DCL int NDECL(def_lomya);
STATIC_DCL int NDECL(def_mountedCombat);
const struct worn {
long w_mask;
long long w_mask;
struct obj **w_obj;
} worn[] = {
{ W_ARM, &uarm },
@ -29,8 +29,14 @@ const struct worn {
#ifdef TOURIST
{ W_ARMU, &uarmu },
#endif
{ W_RINGL, &uleft },
{ W_RINGR, &uright },
{ W_RING0, &urings[0] },
{ W_RING1, &urings[1] },
{ W_RING2, &urings[2] },
{ W_RING3, &urings[3] },
{ W_RING4, &urings[4] },
{ W_RING5, &urings[5] },
{ W_RING6, &urings[6] },
{ W_RING7, &urings[7] },
{ W_WEP, &uwep },
{ W_SWAPWEP, &uswapwep },
{ W_QUIVER, &uquiver },
@ -49,6 +55,73 @@ const struct worn {
/* note: monsters don't have clairvoyance, so your role
has no significant effect on their use of w_blocks() */
const long long ring_index_to_wornmask[] = {
W_RING0, W_RING1, W_RING2, W_RING3, W_RING4, W_RING5, W_RING6, W_RING7
};
/*
* Counts worn rings. If include_non_rings is true, also includes
* non-ring items that block ring slots.
*/
int
count_worn_rings(boolean include_non_rings)
{
int count = 0;
for (int i = 0; i < URINGS_SIZE; i++)
/* urings[1] == right ring */
if (urings[i] || (include_non_rings && i == 1 && uarmg
&& uarmg->oartifact == ART_CLAWS_OF_THE_REVENANCER))
count++;
return count;
}
/*
* Returns index of the first object with a matching otyp in urings,
* or -1 if none is found.
*/
int
uring_otyp_index(int otyp)
{
for (int i = 0; i < URINGS_SIZE; i++)
if (urings[i] && urings[i]->otyp == otyp)
return i;
return -1;
}
/*
* Returns index of the first object with a matching oartifact in
* urings, or -1 if none is found.
*/
int
uring_art_index(int art_num)
{
for (int i = 0; i < URINGS_SIZE; i++)
if (urings[i] && urings[i]->oartifact == art_num)
return i;
return -1;
}
/*
* Returns pointer to the first object with a matching otyp in
* urings, or NULL if none is found.
*/
struct obj *
uring_otyp(int otyp)
{
int index = uring_otyp_index(otyp);
return index == -1 ? NULL : urings[index];
}
/*
* Returns pointer to the first object with a matching oartifact in
* urings, or NULL if none is found.
*/
struct obj *
uring_art(int art_num)
{
int index = uring_art_index(art_num);
return index == -1 ? NULL : urings[index];
}
/* returns TRUE if obj confers prop
* also checks artifact properties
@ -320,7 +393,7 @@ long mask;
for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) {
oobj = *(wp->w_obj);
if(oobj && !(oobj->owornmask & wp->w_mask))
impossible("Setworn: mask = %ld.", wp->w_mask);
impossible("Setworn: mask = %lld.", wp->w_mask);
if(oobj) {
if (u.twoweap && (oobj->owornmask & (W_WEP|W_SWAPWEP)) && !test_twoweapon())
u.twoweap = 0;

View file

@ -42,6 +42,7 @@ struct attack grapple = { AT_HUGS, AD_PHYS, 0, 6 }; /* for grappler's grasp */
struct attack acu_tent = { AT_TENT, AD_DRIN, 1, 4 }; /* for acu tentacles */
struct attack sala_tuch = { AT_TUCH, AD_FIRE, 1, 4 }; /* for sala tuch */
struct attack sala_grab = { AT_HUGS, AD_FIRE, 1, 4 }; /* for sala grab */
struct attack oct_tent = { AT_TENT, AD_WRAP, 1, 8 }; /* for octopode tentacles */
int
check_subout(subout_list, subout)
@ -2133,8 +2134,7 @@ int * tohitmod; /* some attacks are made with decreased accuracy */
if (*indexnum == 0){
if (youdef){
boolean engring = FALSE;
if ((uleft && uleft->otyp == find_engagement_ring()) ||
(uright && uright->otyp == find_engagement_ring()))
if (uring_otyp(find_engagement_ring()))
engring = TRUE;
if(pd && (!(dmgtype(pd, AD_SEDU)
|| dmgtype(pd, AD_SSEX)
@ -2542,6 +2542,10 @@ int * tohitmod; /* some attacks are made with decreased accuracy */
*attk = sala_grab;
add_subout(subout, SUBOUT_SALA2);
}
if (youagr && !Upolyd && Race_if(PM_OCTOPODE) && is_null_attk(attk) && !by_the_book && !check_subout(subout, SUBOUT_OCT)) {
*attk = oct_tent;
add_subout(subout, SUBOUT_OCT);
}
/* players can get a whole host of spirit attacks */
if (youagr && is_null_attk(attk) && !by_the_book) {
@ -7032,7 +7036,7 @@ boolean ranged;
else {
/* Demogorgon tries to kill */
if (pa->mtyp == PM_DEMOGORGON || pa->mtyp == PM_BLIBDOOLPOOLP__GRAVEN_INTO_FLESH) {
if (noncorporeal(pd) || amorphous(pd)) {
if (noncorporeal(pd) || amorphous(pd) || pd->mtyp == PM_OCTOPODE) {
/* custom hit message */
if (vis && dohitmsg) {
pline("%s %s to rip %s apart!",
@ -7825,8 +7829,7 @@ boolean ranged;
break;
case AD_SEDU:
if ((uleft && uleft->otyp == find_engagement_ring()) ||
(uright && uright->otyp == find_engagement_ring()))
if (uring_otyp(find_engagement_ring()))
engring = TRUE;
if (u.sealsActive&SEAL_ANDROMALIUS) break;
//pline("test string!");
@ -7892,8 +7895,7 @@ boolean ranged;
if(Chastity)
break;
if ((uleft && uleft->otyp == find_engagement_ring()) ||
(uright && uright->otyp == find_engagement_ring()))
if (uring_otyp(find_engagement_ring()))
break;
if (notmcan && could_seduce(magr, &youmonst, attk) == 1) {
@ -8783,10 +8785,12 @@ boolean ranged;
/* Gentle squeeze. Restore 1d3 points of sanity. Just kidding. */
else {
dmg = 0;
pline("%s is %s.",
Monnam(mtmp),
(youagr ? "wrapped up in you" : "wrapped tight around you")
);
pline("%s is %s.", Monnam(mtmp),
(youagr
? (magr->mtyp == PM_OCTOPODE
? "wrapped up in your tentacles"
: "wrapped up in you")
: "wrapped tight around you"));
}
}
/* nothing really happens */
@ -13000,8 +13004,7 @@ int vis;
/* STRAIGHT COPY-PASTE FROM ORIGINAL */
else {
boolean engring = FALSE;
if ((uleft && uleft->otyp == find_engagement_ring()) ||
(uright && uright->otyp == find_engagement_ring()))
if (uring_otyp(find_engagement_ring()))
engring = TRUE;
if (u.sealsActive&SEAL_ANDROMALIUS) break;
if (distu(magr->mx, magr->my) > 1 ||
@ -13080,8 +13083,7 @@ int vis;
else {
if(Chastity)
break;
if ((uleft && uleft->otyp == find_engagement_ring()) ||
(uright && uright->otyp == find_engagement_ring()))
if (uring_otyp(find_engagement_ring()))
break;
if (could_seduce(magr, &youmonst, attk) == 1
&& !magr->mcan
@ -15710,9 +15712,8 @@ int vis; /* True if action is at all visible to the player */
}
/* all valid attacks proc effects of offensive rings */
if(youagr){
struct obj *rings[] = {uleft, uright};
for(int i = 0 ; i < 2; i++){
otmp = rings[i];
for(int i = 0 ; i < URINGS_SIZE; i++){
otmp = urings[i];
if(!otmp)
continue;
// Note: artifact rings are currently set to always add their damage, but to only print the generic x hits messages when unarmed.

View file

@ -1123,36 +1123,35 @@ void
cancel_item(obj)
register struct obj *obj;
{
boolean u_ring = (obj == uleft) || (obj == uright);
register boolean holy = (obj->otyp == POT_WATER && obj->blessed);
adj_abon(obj, -obj->spe);
switch(obj->otyp) {
case RIN_GAIN_STRENGTH:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_STR) -= obj->spe;
flags.botl = 1;
}
break;
case RIN_GAIN_CONSTITUTION:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_CON) -= obj->spe;
flags.botl = 1;
}
break;
case RIN_ADORNMENT:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_CHA) -= obj->spe;
flags.botl = 1;
}
break;
case RIN_INCREASE_ACCURACY:
if ((obj->owornmask & W_RING) && u_ring)
if (obj->owornmask & W_RING)
u.uhitinc -= obj->spe;
break;
case RIN_INCREASE_DAMAGE:
if ((obj->owornmask & W_RING) && u_ring)
if (obj->owornmask & W_RING)
u.udaminc -= obj->spe;
break;
/* case RIN_PROTECTION: not needed */
@ -1334,8 +1333,6 @@ boolean
drain_item(obj)
struct obj *obj;
{
boolean u_ring;
/* Is this a charged/enchanted object? */
if (!obj || (!objects[obj->otyp].oc_charged &&
obj->oclass != WEAPON_CLASS &&
@ -1352,32 +1349,31 @@ struct obj *obj;
/* Drain the object and any implied effects */
obj->spe--;
u_ring = (obj == uleft) || (obj == uright);
switch(obj->otyp) {
case RIN_GAIN_STRENGTH:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_STR)--;
flags.botl = 1;
}
break;
case RIN_GAIN_CONSTITUTION:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_CON)--;
flags.botl = 1;
}
break;
case RIN_ADORNMENT:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_CHA)--;
flags.botl = 1;
}
break;
case RIN_INCREASE_ACCURACY:
if ((obj->owornmask & W_RING) && u_ring)
if (obj->owornmask & W_RING)
u.uhitinc--;
break;
case RIN_INCREASE_DAMAGE:
if ((obj->owornmask & W_RING) && u_ring)
if (obj->owornmask & W_RING)
u.udaminc--;
break;
case RIN_PROTECTION:
@ -1395,8 +1391,6 @@ boolean
damage_item(obj)
register struct obj *obj;
{
boolean u_ring;
/* Is this a charged/enchanted object? */
if (!obj || (!objects[obj->otyp].oc_charged &&
obj->oclass != WEAPON_CLASS &&
@ -1412,32 +1406,31 @@ register struct obj *obj;
/* Drain the object and any implied effects */
obj->spe--;
u_ring = (obj == uleft) || (obj == uright);
switch(obj->otyp) {
case RIN_GAIN_STRENGTH:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_STR)--;
flags.botl = 1;
}
break;
case RIN_GAIN_CONSTITUTION:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_CON)--;
flags.botl = 1;
}
break;
case RIN_ADORNMENT:
if ((obj->owornmask & W_RING) && u_ring) {
if (obj->owornmask & W_RING) {
ABON(A_CHA)--;
flags.botl = 1;
}
break;
case RIN_INCREASE_ACCURACY:
if ((obj->owornmask & W_RING) && u_ring)
if (obj->owornmask & W_RING)
u.uhitinc--;
break;
case RIN_INCREASE_DAMAGE:
if ((obj->owornmask & W_RING) && u_ring)
if (obj->owornmask & W_RING)
u.udaminc--;
break;
case RIN_PROTECTION:
@ -1977,10 +1970,9 @@ int id;
otmp->owornmask = obj->owornmask;
remove_worn_item(obj, TRUE);
setworn(otmp, otmp->owornmask);
if (otmp->owornmask & LEFT_RING)
uleft = otmp;
if (otmp->owornmask & RIGHT_RING)
uright = otmp;
for (int i = 0; i < URINGS_SIZE; i++)
if (otmp->owornmask & ring_index_to_wornmask[i])
urings[i] = otmp;
if (otmp->owornmask & W_WEP)
uwep = otmp;
if (otmp->owornmask & W_SWAPWEP)