Artifact and #offer rebalance, part 1: sacrifice gifts
In 3.6, artifact gifts are often either a) entirely useless or b) gamebreaking, neither of which is really ideal from a balance perspective. This commit aims to make artifact gifts more useful in the early game by greatly increasing the chance for situational artifacts to generate positively enchanted. However, the most powerful artifacts will now only be gifted if you offer a high-value corpse, meaning that they are only likely to be accessible later in the game. The selection of which artifact to gift has become more complicated in order to a) increase the chance that it fits the character and b) reduce cheese strategies (e.g. it is no longer possible for elves to force the gifting of Stormbringer as the first sacrifice gift).
This commit is contained in:
@@ -1486,6 +1486,10 @@ digging in ice was handled inconsistently, particularly if done at the span
|
|||||||
angry god may remove an intrinsic
|
angry god may remove an intrinsic
|
||||||
gelatinous cubes eat organic objects inside them
|
gelatinous cubes eat organic objects inside them
|
||||||
pets with reflection were unwilling to attack floating eyes
|
pets with reflection were unwilling to attack floating eyes
|
||||||
|
artifact gifts are rebalanced (easier to obtain; higher-value sacrifices are
|
||||||
|
needed for higher-value artifacts; lower-value artifacts are usually
|
||||||
|
gifted enchanted; unaligned artifacts are possible but rare even on
|
||||||
|
the first gift; artifacts you can't use well are less likely)
|
||||||
|
|
||||||
|
|
||||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||||
|
|||||||
@@ -49,6 +49,8 @@ struct artifact {
|
|||||||
aligntyp alignment; /* alignment of bequeathing gods */
|
aligntyp alignment; /* alignment of bequeathing gods */
|
||||||
short role; /* character role associated with */
|
short role; /* character role associated with */
|
||||||
short race; /* character race associated with */
|
short race; /* character race associated with */
|
||||||
|
schar gen_spe; /* bias to spe when gifted or randomly generated */
|
||||||
|
uchar gift_value; /* minimum sacrifice value to be gifted this */
|
||||||
long cost; /* price when sold to hero (default 100 x base cost) */
|
long cost; /* price when sold to hero (default 100 x base cost) */
|
||||||
char acolor; /* color to use if artifact 'glows' */
|
char acolor; /* color to use if artifact 'glows' */
|
||||||
};
|
};
|
||||||
|
|||||||
+93
-59
@@ -7,28 +7,28 @@
|
|||||||
/* in makedefs.c, all we care about is the list of names */
|
/* in makedefs.c, all we care about is the list of names */
|
||||||
|
|
||||||
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
||||||
cost, clr, bn) nam
|
gs, gv, cost, clr, bn) nam
|
||||||
|
|
||||||
static const char *const artifact_names[] = {
|
static const char *const artifact_names[] = {
|
||||||
|
|
||||||
#elif defined(ARTI_ENUM)
|
#elif defined(ARTI_ENUM)
|
||||||
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
||||||
cost, clr, bn) \
|
gs, gv, cost, clr, bn) \
|
||||||
ART_##bn
|
ART_##bn
|
||||||
|
|
||||||
#elif defined(DUMP_ARTI_ENUM)
|
#elif defined(DUMP_ARTI_ENUM)
|
||||||
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
||||||
cost, clr, bn) \
|
gs, gv, cost, clr, bn) \
|
||||||
{ ART_##bn, "ART_" #bn }
|
{ ART_##bn, "ART_" #bn }
|
||||||
#else
|
#else
|
||||||
/* in artifact.c, set up the actual artifact list structure;
|
/* in artifact.c, set up the actual artifact list structure;
|
||||||
color field is for an artifact when it glows, not for the item itself */
|
color field is for an artifact when it glows, not for the item itself */
|
||||||
|
|
||||||
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
#define A(nam, typ, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
||||||
cost, clr, bn) \
|
gs, gv, cost, clr, bn) \
|
||||||
{ \
|
{ \
|
||||||
typ, nam, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
typ, nam, s1, s2, mt, atk, dfn, cry, inv, al, cl, rac, \
|
||||||
cost, clr \
|
gs, gv, cost, clr \
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
@@ -52,24 +52,47 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
* 1. The more useful the artifact, the better its cost.
|
* 1. The more useful the artifact, the better its cost.
|
||||||
* 2. Quest artifacts are highly valued.
|
* 2. Quest artifacts are highly valued.
|
||||||
* 3. Chaotic artifacts are inflated due to scarcity (and balance).
|
* 3. Chaotic artifacts are inflated due to scarcity (and balance).
|
||||||
|
*
|
||||||
|
* Artifact gen_spe rationale:
|
||||||
|
* 1. If the artifact is useful against most enemies, +0.
|
||||||
|
* 2. If the artifact is useful against only a few enemies, usually +2.
|
||||||
|
* This gives the artifact use to early-game characters who receive
|
||||||
|
* it as a gift or find it on the ground.
|
||||||
|
* 3. Role gift gen_spe is chosen to balance against the role's
|
||||||
|
* default starting weapon (it should be better, but need not be
|
||||||
|
* much better).
|
||||||
|
* 4. This can be modified as required for special cases.
|
||||||
|
* (In some cases, like Excalibur, the value is irrelevant.)
|
||||||
|
* 5. Nonweapon spe may have a special meaning, so gen_spe for
|
||||||
|
* nonweapons must always be 0.
|
||||||
|
*
|
||||||
|
* Artifact gift_value is chosen so that "endgame-quality" artifacts are
|
||||||
|
* not gifted in the early game (so that characters don't grind on an
|
||||||
|
* altar early-game until they have their endgame weapon, then use it to
|
||||||
|
* carry them through the game). Those artifacts have values ranging from
|
||||||
|
* around 8 to 10, based on how good the artifact is. Less powerful
|
||||||
|
* artifacts have values in the 1 to 5 range. Values in between are used
|
||||||
|
* for conditionally good artifacts. (Note that the value of a gift is
|
||||||
|
* normally 1 higher than the difficulty of the monster.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* dummy element #0, so that all interesting indices are non-zero */
|
/* dummy element #0, so that all interesting indices are non-zero */
|
||||||
A("", STRANGE_OBJECT, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE,
|
A("", STRANGE_OBJECT, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE,
|
||||||
NON_PM, NON_PM, 0L, NO_COLOR, NONARTIFACT),
|
NON_PM, NON_PM,
|
||||||
|
0, 0, 0L, NO_COLOR, NONARTIFACT),
|
||||||
|
|
||||||
A("Excalibur", LONG_SWORD, (SPFX_NOGEN | SPFX_RESTR | SPFX_SEEK
|
A("Excalibur", LONG_SWORD, (SPFX_NOGEN | SPFX_RESTR | SPFX_SEEK
|
||||||
| SPFX_DEFN | SPFX_INTEL | SPFX_SEARCH),
|
| SPFX_DEFN | SPFX_INTEL | SPFX_SEARCH),
|
||||||
0, 0, PHYS(5, 10), DRLI(0, 0), NO_CARY, 0, A_LAWFUL, PM_KNIGHT, NON_PM,
|
0, 0, PHYS(5, 10), DRLI(0, 0), NO_CARY, 0, A_LAWFUL, PM_KNIGHT, NON_PM,
|
||||||
4000L, NO_COLOR, EXCALIBUR),
|
0, 10, 4000L, NO_COLOR, EXCALIBUR),
|
||||||
/*
|
/*
|
||||||
* Stormbringer only has a 2 because it can drain a level,
|
* Stormbringer only has a 2 because it can drain a level,
|
||||||
* providing 8 more.
|
* providing 8 more.
|
||||||
*/
|
*/
|
||||||
A("Stormbringer", RUNESWORD,
|
A("Stormbringer", RUNESWORD,
|
||||||
(SPFX_RESTR | SPFX_ATTK | SPFX_DEFN | SPFX_INTEL | SPFX_DRLI), 0, 0,
|
(SPFX_RESTR | SPFX_ATTK | SPFX_DEFN | SPFX_INTEL | SPFX_DRLI), 0, 0,
|
||||||
DRLI(5, 2), DRLI(0, 0), NO_CARY, 0, A_CHAOTIC, NON_PM, NON_PM, 8000L,
|
DRLI(5, 2), DRLI(0, 0), NO_CARY, 0, A_CHAOTIC, NON_PM, NON_PM,
|
||||||
NO_COLOR, STORMBRINGER),
|
0, 9, 8000L, NO_COLOR, STORMBRINGER),
|
||||||
/*
|
/*
|
||||||
* Mjollnir can be thrown when wielded if hero has 25 Strength
|
* Mjollnir can be thrown when wielded if hero has 25 Strength
|
||||||
* (usually via gauntlets of power but possible with rings of
|
* (usually via gauntlets of power but possible with rings of
|
||||||
@@ -84,10 +107,12 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
*/
|
*/
|
||||||
A("Mjollnir", WAR_HAMMER, /* Mjo:llnir */
|
A("Mjollnir", WAR_HAMMER, /* Mjo:llnir */
|
||||||
(SPFX_RESTR | SPFX_ATTK), 0, 0, ELEC(5, 24), NO_DFNS, NO_CARY, 0,
|
(SPFX_RESTR | SPFX_ATTK), 0, 0, ELEC(5, 24), NO_DFNS, NO_CARY, 0,
|
||||||
A_NEUTRAL, PM_VALKYRIE, NON_PM, 4000L, NO_COLOR, MJOLLNIR),
|
A_NEUTRAL, PM_VALKYRIE, NON_PM,
|
||||||
|
0, 8, 4000L, NO_COLOR, MJOLLNIR),
|
||||||
|
|
||||||
A("Cleaver", BATTLE_AXE, SPFX_RESTR, 0, 0, PHYS(3, 6), NO_DFNS, NO_CARY,
|
A("Cleaver", BATTLE_AXE, SPFX_RESTR, 0, 0, PHYS(3, 6), NO_DFNS, NO_CARY,
|
||||||
0, A_NEUTRAL, PM_BARBARIAN, NON_PM, 1500L, NO_COLOR, CLEAVER),
|
0, A_NEUTRAL, PM_BARBARIAN, NON_PM,
|
||||||
|
0, 8, 1500L, NO_COLOR, CLEAVER),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Grimtooth glows in warning when elves are present, but its
|
* Grimtooth glows in warning when elves are present, but its
|
||||||
@@ -96,7 +121,8 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
*/
|
*/
|
||||||
A("Grimtooth", ORCISH_DAGGER, (SPFX_RESTR | SPFX_WARN | SPFX_DFLAG2),
|
A("Grimtooth", ORCISH_DAGGER, (SPFX_RESTR | SPFX_WARN | SPFX_DFLAG2),
|
||||||
0, M2_ELF, PHYS(2, 6), NO_DFNS,
|
0, M2_ELF, PHYS(2, 6), NO_DFNS,
|
||||||
NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ORC, 300L, CLR_RED, GRIMTOOTH),
|
NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ORC,
|
||||||
|
0, 5, 300L, CLR_RED, GRIMTOOTH),
|
||||||
/*
|
/*
|
||||||
* Orcrist and Sting have same alignment as elves.
|
* Orcrist and Sting have same alignment as elves.
|
||||||
*
|
*
|
||||||
@@ -105,56 +131,56 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
* Sting and Orcrist will warn of M2_ORC monsters.
|
* Sting and Orcrist will warn of M2_ORC monsters.
|
||||||
*/
|
*/
|
||||||
A("Orcrist", ELVEN_BROADSWORD, (SPFX_WARN | SPFX_DFLAG2), 0, M2_ORC,
|
A("Orcrist", ELVEN_BROADSWORD, (SPFX_WARN | SPFX_DFLAG2), 0, M2_ORC,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF, 2000L,
|
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF,
|
||||||
CLR_BRIGHT_BLUE, ORCRIST), /* bright blue is actually light blue */
|
3, 4, 2000L, CLR_BRIGHT_BLUE, ORCRIST), /* actually light blue */
|
||||||
|
|
||||||
A("Sting", ELVEN_DAGGER, (SPFX_WARN | SPFX_DFLAG2), 0, M2_ORC,
|
A("Sting", ELVEN_DAGGER, (SPFX_WARN | SPFX_DFLAG2), 0, M2_ORC,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF, 800L,
|
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_CHAOTIC, NON_PM, PM_ELF,
|
||||||
CLR_BRIGHT_BLUE, STING),
|
3, 1, 800L, CLR_BRIGHT_BLUE, STING),
|
||||||
/*
|
/*
|
||||||
* Magicbane is a bit different! Its magic fanfare
|
* Magicbane is a bit different! Its magic fanfare
|
||||||
* unbalances victims in addition to doing some damage.
|
* unbalances victims in addition to doing some damage.
|
||||||
*/
|
*/
|
||||||
A("Magicbane", ATHAME, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0,
|
A("Magicbane", ATHAME, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0,
|
||||||
STUN(3, 4), DFNS(AD_MAGM), NO_CARY, 0, A_NEUTRAL, PM_WIZARD, NON_PM,
|
STUN(3, 4), DFNS(AD_MAGM), NO_CARY, 0, A_NEUTRAL, PM_WIZARD, NON_PM,
|
||||||
3500L, NO_COLOR, MAGICBANE),
|
0, 7, 3500L, NO_COLOR, MAGICBANE),
|
||||||
|
|
||||||
A("Frost Brand", LONG_SWORD, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0,
|
A("Frost Brand", LONG_SWORD, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0,
|
||||||
COLD(5, 0), COLD(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L,
|
COLD(5, 0), COLD(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM,
|
||||||
NO_COLOR, FROST_BRAND),
|
0, 9, 3000L, NO_COLOR, FROST_BRAND),
|
||||||
|
|
||||||
A("Fire Brand", LONG_SWORD, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0,
|
A("Fire Brand", LONG_SWORD, (SPFX_RESTR | SPFX_ATTK | SPFX_DEFN), 0, 0,
|
||||||
FIRE(5, 0), FIRE(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 3000L,
|
FIRE(5, 0), FIRE(0, 0), NO_CARY, 0, A_NONE, NON_PM, NON_PM,
|
||||||
NO_COLOR, FIRE_BRAND),
|
0, 5, 3000L, NO_COLOR, FIRE_BRAND),
|
||||||
|
|
||||||
A("Dragonbane", BROADSWORD,
|
A("Dragonbane", BROADSWORD,
|
||||||
(SPFX_RESTR | SPFX_DCLAS | SPFX_REFLECT), 0, S_DRAGON,
|
(SPFX_RESTR | SPFX_DCLAS | SPFX_REFLECT), 0, S_DRAGON,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 500L,
|
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM,
|
||||||
NO_COLOR, DRAGONBANE),
|
2, 5, 500L, NO_COLOR, DRAGONBANE),
|
||||||
|
|
||||||
A("Demonbane", MACE, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_DEMON,
|
A("Demonbane", MACE, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_DEMON,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, BANISH, A_LAWFUL, PM_CLERIC, NON_PM,
|
PHYS(5, 0), NO_DFNS, NO_CARY, BANISH, A_LAWFUL, PM_CLERIC, NON_PM,
|
||||||
2500L, NO_COLOR, DEMONBANE),
|
1, 3, 2500L, NO_COLOR, DEMONBANE),
|
||||||
|
|
||||||
A("Werebane", SILVER_SABER, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_WERE,
|
A("Werebane", SILVER_SABER, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_WERE,
|
||||||
PHYS(5, 0), DFNS(AD_WERE), NO_CARY, 0, A_NONE, NON_PM, NON_PM, 1500L,
|
PHYS(5, 0), DFNS(AD_WERE), NO_CARY, 0, A_NONE, NON_PM, NON_PM,
|
||||||
NO_COLOR, WEREBANE),
|
1, 4, 1500L, NO_COLOR, WEREBANE),
|
||||||
|
|
||||||
A("Grayswandir", SILVER_SABER, (SPFX_RESTR | SPFX_HALRES), 0, 0,
|
A("Grayswandir", SILVER_SABER, (SPFX_RESTR | SPFX_HALRES), 0, 0,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM, 8000L,
|
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_LAWFUL, NON_PM, NON_PM,
|
||||||
NO_COLOR, GRAYSWANDIR),
|
0, 10, 8000L, NO_COLOR, GRAYSWANDIR),
|
||||||
|
|
||||||
A("Giantslayer", LONG_SWORD, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_GIANT,
|
A("Giantslayer", LONG_SWORD, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_GIANT,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 200L,
|
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM,
|
||||||
NO_COLOR, GIANTSLAYER),
|
2, 4, 200L, NO_COLOR, GIANTSLAYER),
|
||||||
|
|
||||||
A("Ogresmasher", WAR_HAMMER, (SPFX_RESTR | SPFX_DCLAS), 0, S_OGRE,
|
A("Ogresmasher", WAR_HAMMER, (SPFX_RESTR | SPFX_DCLAS), 0, S_OGRE,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L,
|
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM,
|
||||||
NO_COLOR, OGRESMASHER),
|
2, 1, 200L, NO_COLOR, OGRESMASHER),
|
||||||
|
|
||||||
A("Trollsbane", MORNING_STAR, (SPFX_RESTR | SPFX_DCLAS), 0, S_TROLL,
|
A("Trollsbane", MORNING_STAR, (SPFX_RESTR | SPFX_DCLAS), 0, S_TROLL,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 200L,
|
PHYS(5, 0), NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM,
|
||||||
NO_COLOR, TROLLSBANE),
|
2, 1, 200L, NO_COLOR, TROLLSBANE),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Two problems: 1) doesn't let trolls regenerate heads,
|
* Two problems: 1) doesn't let trolls regenerate heads,
|
||||||
@@ -162,8 +188,8 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
* allowing those at all causes more problems than worth the effort).
|
* allowing those at all causes more problems than worth the effort).
|
||||||
*/
|
*/
|
||||||
A("Vorpal Blade", LONG_SWORD, (SPFX_RESTR | SPFX_BEHEAD), 0, 0,
|
A("Vorpal Blade", LONG_SWORD, (SPFX_RESTR | SPFX_BEHEAD), 0, 0,
|
||||||
PHYS(5, 1), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM, 4000L,
|
PHYS(5, 1), NO_DFNS, NO_CARY, 0, A_NEUTRAL, NON_PM, NON_PM,
|
||||||
NO_COLOR, VORPAL_BLADE),
|
1, 5, 4000L, NO_COLOR, VORPAL_BLADE),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Ah, never shall I forget the cry,
|
* Ah, never shall I forget the cry,
|
||||||
@@ -174,33 +200,38 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
* (From Sir W.S. Gilbert's "The Mikado")
|
* (From Sir W.S. Gilbert's "The Mikado")
|
||||||
*/
|
*/
|
||||||
A("Snickersnee", KATANA, SPFX_RESTR, 0, 0, PHYS(0, 8), NO_DFNS, NO_CARY,
|
A("Snickersnee", KATANA, SPFX_RESTR, 0, 0, PHYS(0, 8), NO_DFNS, NO_CARY,
|
||||||
0, A_LAWFUL, PM_SAMURAI, NON_PM, 1200L, NO_COLOR, SNICKERSNEE),
|
0, A_LAWFUL, PM_SAMURAI, NON_PM,
|
||||||
|
0, 8, 1200L, NO_COLOR, SNICKERSNEE),
|
||||||
|
|
||||||
/* Sunsword emits light when wielded (handled in the core rather than
|
/* Sunsword emits light when wielded (handled in the core rather than
|
||||||
via artifact fields), but that light has no particular color */
|
via artifact fields), but that light has no particular color */
|
||||||
A("Sunsword", LONG_SWORD, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_UNDEAD,
|
A("Sunsword", LONG_SWORD, (SPFX_RESTR | SPFX_DFLAG2), 0, M2_UNDEAD,
|
||||||
PHYS(5, 0), DFNS(AD_BLND), NO_CARY, BLINDING_RAY, A_LAWFUL, NON_PM,
|
PHYS(5, 0), DFNS(AD_BLND), NO_CARY, BLINDING_RAY, A_LAWFUL, NON_PM,
|
||||||
NON_PM, 1500L, NO_COLOR, SUNSWORD),
|
NON_PM,
|
||||||
|
0, 6, 1500L, NO_COLOR, SUNSWORD),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The artifacts for the quest dungeon, all self-willed.
|
* The artifacts for the quest dungeon, all self-willed.
|
||||||
|
* gen_spe should be 0; gift_value irrelevant and set to 12.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
A("The Orb of Detection", CRYSTAL_BALL,
|
A("The Orb of Detection", CRYSTAL_BALL,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), (SPFX_ESP | SPFX_HSPDAM), 0,
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), (SPFX_ESP | SPFX_HSPDAM), 0,
|
||||||
NO_ATTK, NO_DFNS, CARY(AD_MAGM), INVIS, A_LAWFUL, PM_ARCHEOLOGIST,
|
NO_ATTK, NO_DFNS, CARY(AD_MAGM), INVIS, A_LAWFUL, PM_ARCHEOLOGIST,
|
||||||
NON_PM, 2500L, NO_COLOR, ORB_OF_DETECTION),
|
NON_PM,
|
||||||
|
0, 12, 2500L, NO_COLOR, ORB_OF_DETECTION),
|
||||||
|
|
||||||
A("The Heart of Ahriman", LUCKSTONE,
|
A("The Heart of Ahriman", LUCKSTONE,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), SPFX_STLTH, 0,
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), SPFX_STLTH, 0,
|
||||||
/* this stone does double damage if used as a projectile weapon */
|
/* this stone does double damage if used as a projectile weapon */
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, LEVITATION, A_NEUTRAL, PM_BARBARIAN,
|
PHYS(5, 0), NO_DFNS, NO_CARY, LEVITATION, A_NEUTRAL, PM_BARBARIAN,
|
||||||
NON_PM, 2500L, NO_COLOR, HEART_OF_AHRIMAN),
|
NON_PM,
|
||||||
|
0, 12, 2500L, NO_COLOR, HEART_OF_AHRIMAN),
|
||||||
|
|
||||||
A("The Sceptre of Might", MACE,
|
A("The Sceptre of Might", MACE,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DALIGN), 0, 0, PHYS(5, 0),
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DALIGN), 0, 0, PHYS(5, 0),
|
||||||
DFNS(AD_MAGM), NO_CARY, CONFLICT, A_LAWFUL, PM_CAVE_DWELLER, NON_PM,
|
DFNS(AD_MAGM), NO_CARY, CONFLICT, A_LAWFUL, PM_CAVE_DWELLER, NON_PM,
|
||||||
2500L, NO_COLOR, SCEPTRE_OF_MIGHT),
|
0, 12, 2500L, NO_COLOR, SCEPTRE_OF_MIGHT),
|
||||||
|
|
||||||
#if 0 /* OBSOLETE -- from 3.1.0 to 3.2.x, this was quest artifact for the
|
#if 0 /* OBSOLETE -- from 3.1.0 to 3.2.x, this was quest artifact for the
|
||||||
* Elf role; in 3.3.0 elf became a race available to several roles
|
* Elf role; in 3.3.0 elf became a race available to several roles
|
||||||
@@ -209,35 +240,37 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
A("The Palantir of Westernesse", CRYSTAL_BALL,
|
A("The Palantir of Westernesse", CRYSTAL_BALL,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL),
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL),
|
||||||
(SPFX_ESP | SPFX_REGEN | SPFX_HSPDAM), 0,
|
(SPFX_ESP | SPFX_REGEN | SPFX_HSPDAM), 0,
|
||||||
NO_ATTK, NO_DFNS, NO_CARY, TAMING, A_CHAOTIC, NON_PM, PM_ELF, 8000L,
|
NO_ATTK, NO_DFNS, NO_CARY, TAMING, A_CHAOTIC, NON_PM, PM_ELF,
|
||||||
NO_COLOR, PALANTIR_OF_WESTERNESSE),
|
0, 12, 8000L, NO_COLOR, PALANTIR_OF_WESTERNESSE),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
A("The Staff of Aesculapius", QUARTERSTAFF,
|
A("The Staff of Aesculapius", QUARTERSTAFF,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_ATTK | SPFX_INTEL | SPFX_DRLI
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_ATTK | SPFX_INTEL | SPFX_DRLI
|
||||||
| SPFX_REGEN),
|
| SPFX_REGEN),
|
||||||
0, 0, DRLI(0, 0), DRLI(0, 0), NO_CARY, HEALING, A_NEUTRAL, PM_HEALER,
|
0, 0, DRLI(0, 0), DRLI(0, 0), NO_CARY, HEALING, A_NEUTRAL, PM_HEALER,
|
||||||
NON_PM, 5000L, NO_COLOR, STAFF_OF_AESCULAPIUS),
|
NON_PM,
|
||||||
|
0, 12, 5000L, NO_COLOR, STAFF_OF_AESCULAPIUS),
|
||||||
|
|
||||||
A("The Magic Mirror of Merlin", MIRROR,
|
A("The Magic Mirror of Merlin", MIRROR,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK), SPFX_ESP, 0,
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK), SPFX_ESP, 0,
|
||||||
NO_ATTK, NO_DFNS, CARY(AD_MAGM), 0, A_LAWFUL, PM_KNIGHT, NON_PM, 1500L,
|
NO_ATTK, NO_DFNS, CARY(AD_MAGM), 0, A_LAWFUL, PM_KNIGHT, NON_PM,
|
||||||
NO_COLOR, MAGIC_MIRROR_OF_MERLIN),
|
0, 12, 1500L, NO_COLOR, MAGIC_MIRROR_OF_MERLIN),
|
||||||
|
|
||||||
A("The Eyes of the Overworld", LENSES,
|
A("The Eyes of the Overworld", LENSES,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_XRAY), 0, 0, NO_ATTK,
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_XRAY), 0, 0, NO_ATTK,
|
||||||
DFNS(AD_MAGM), NO_CARY, ENLIGHTENING, A_NEUTRAL, PM_MONK, NON_PM,
|
DFNS(AD_MAGM), NO_CARY, ENLIGHTENING, A_NEUTRAL, PM_MONK, NON_PM,
|
||||||
2500L, NO_COLOR, EYES_OF_THE_OVERWORLD),
|
0, 12, 2500L, NO_COLOR, EYES_OF_THE_OVERWORLD),
|
||||||
|
|
||||||
A("The Mitre of Holiness", HELM_OF_BRILLIANCE,
|
A("The Mitre of Holiness", HELM_OF_BRILLIANCE,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_DFLAG2 | SPFX_INTEL | SPFX_PROTECT), 0,
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_DFLAG2 | SPFX_INTEL | SPFX_PROTECT), 0,
|
||||||
M2_UNDEAD, NO_ATTK, NO_DFNS, CARY(AD_FIRE), ENERGY_BOOST, A_LAWFUL,
|
M2_UNDEAD, NO_ATTK, NO_DFNS, CARY(AD_FIRE), ENERGY_BOOST, A_LAWFUL,
|
||||||
PM_CLERIC, NON_PM, 2000L, NO_COLOR, MITRE_OF_HOLINESS),
|
PM_CLERIC, NON_PM,
|
||||||
|
0, 12, 2000L, NO_COLOR, MITRE_OF_HOLINESS),
|
||||||
|
|
||||||
A("The Longbow of Diana", BOW,
|
A("The Longbow of Diana", BOW,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_REFLECT), SPFX_ESP, 0,
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_REFLECT), SPFX_ESP, 0,
|
||||||
PHYS(5, 0), NO_DFNS, NO_CARY, CREATE_AMMO, A_CHAOTIC, PM_RANGER, NON_PM,
|
PHYS(5, 0), NO_DFNS, NO_CARY, CREATE_AMMO, A_CHAOTIC, PM_RANGER, NON_PM,
|
||||||
4000L, NO_COLOR, LONGBOW_OF_DIANA),
|
0, 12, 4000L, NO_COLOR, LONGBOW_OF_DIANA),
|
||||||
|
|
||||||
/* MKoT has an additional carry property if the Key is not cursed (for
|
/* MKoT has an additional carry property if the Key is not cursed (for
|
||||||
rogues) or blessed (for non-rogues): #untrap of doors and chests
|
rogues) or blessed (for non-rogues): #untrap of doors and chests
|
||||||
@@ -245,38 +278,39 @@ static NEARDATA struct artifact artilist[] = {
|
|||||||
A("The Master Key of Thievery", SKELETON_KEY,
|
A("The Master Key of Thievery", SKELETON_KEY,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK),
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_SPEAK),
|
||||||
(SPFX_WARN | SPFX_TCTRL | SPFX_HPHDAM), 0, NO_ATTK, NO_DFNS, NO_CARY,
|
(SPFX_WARN | SPFX_TCTRL | SPFX_HPHDAM), 0, NO_ATTK, NO_DFNS, NO_CARY,
|
||||||
UNTRAP, A_CHAOTIC, PM_ROGUE, NON_PM, 3500L, NO_COLOR,
|
UNTRAP, A_CHAOTIC, PM_ROGUE, NON_PM,
|
||||||
MASTER_KEY_OF_THIEVERY),
|
0, 12, 3500L, NO_COLOR, MASTER_KEY_OF_THIEVERY),
|
||||||
|
|
||||||
A("The Tsurugi of Muramasa", TSURUGI,
|
A("The Tsurugi of Muramasa", TSURUGI,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_BEHEAD | SPFX_LUCK
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_BEHEAD | SPFX_LUCK
|
||||||
| SPFX_PROTECT),
|
| SPFX_PROTECT),
|
||||||
0, 0, PHYS(0, 8), NO_DFNS, NO_CARY, 0, A_LAWFUL, PM_SAMURAI, NON_PM,
|
0, 0, PHYS(0, 8), NO_DFNS, NO_CARY, 0, A_LAWFUL, PM_SAMURAI, NON_PM,
|
||||||
4500L, NO_COLOR, TSURUGI_OF_MURAMASA),
|
0, 12, 4500L, NO_COLOR, TSURUGI_OF_MURAMASA),
|
||||||
|
|
||||||
A("The Platinum Yendorian Express Card", CREDIT_CARD,
|
A("The Platinum Yendorian Express Card", CREDIT_CARD,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DEFN),
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_DEFN),
|
||||||
(SPFX_ESP | SPFX_HSPDAM), 0, NO_ATTK, NO_DFNS, CARY(AD_MAGM),
|
(SPFX_ESP | SPFX_HSPDAM), 0, NO_ATTK, NO_DFNS, CARY(AD_MAGM),
|
||||||
CHARGE_OBJ, A_NEUTRAL, PM_TOURIST, NON_PM, 7000L, NO_COLOR,
|
CHARGE_OBJ, A_NEUTRAL, PM_TOURIST, NON_PM,
|
||||||
YENDORIAN_EXPRESS_CARD),
|
0, 12, 7000L, NO_COLOR, YENDORIAN_EXPRESS_CARD),
|
||||||
|
|
||||||
A("The Orb of Fate", CRYSTAL_BALL,
|
A("The Orb of Fate", CRYSTAL_BALL,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_LUCK),
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL | SPFX_LUCK),
|
||||||
(SPFX_WARN | SPFX_HSPDAM | SPFX_HPHDAM), 0, NO_ATTK, NO_DFNS, NO_CARY,
|
(SPFX_WARN | SPFX_HSPDAM | SPFX_HPHDAM), 0, NO_ATTK, NO_DFNS, NO_CARY,
|
||||||
LEV_TELE, A_NEUTRAL, PM_VALKYRIE, NON_PM, 3500L, NO_COLOR,
|
LEV_TELE, A_NEUTRAL, PM_VALKYRIE, NON_PM,
|
||||||
ORB_OF_FATE),
|
0, 12, 3500L, NO_COLOR, ORB_OF_FATE),
|
||||||
|
|
||||||
A("The Eye of the Aethiopica", AMULET_OF_ESP,
|
A("The Eye of the Aethiopica", AMULET_OF_ESP,
|
||||||
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), (SPFX_EREGEN | SPFX_HSPDAM), 0,
|
(SPFX_NOGEN | SPFX_RESTR | SPFX_INTEL), (SPFX_EREGEN | SPFX_HSPDAM), 0,
|
||||||
NO_ATTK, DFNS(AD_MAGM), NO_CARY, CREATE_PORTAL, A_NEUTRAL, PM_WIZARD,
|
NO_ATTK, DFNS(AD_MAGM), NO_CARY, CREATE_PORTAL, A_NEUTRAL, PM_WIZARD,
|
||||||
NON_PM, 4000L, NO_COLOR, EYE_OF_THE_AETHIOPICA),
|
NON_PM,
|
||||||
|
0, 12, 4000L, NO_COLOR, EYE_OF_THE_AETHIOPICA),
|
||||||
|
|
||||||
#if !defined(ARTI_ENUM) && !defined(DUMP_ARTI_ENUM)
|
#if !defined(ARTI_ENUM) && !defined(DUMP_ARTI_ENUM)
|
||||||
/*
|
/*
|
||||||
* terminator; otyp must be zero
|
* terminator; otyp must be zero
|
||||||
*/
|
*/
|
||||||
A(0, 0, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM, 0L,
|
A(0, 0, 0, 0, 0, NO_ATTK, NO_DFNS, NO_CARY, 0, A_NONE, NON_PM, NON_PM,
|
||||||
NO_COLOR, TERMINATOR)
|
0, 0, 0L, NO_COLOR, TERMINATOR)
|
||||||
|
|
||||||
}; /* artilist[] (or artifact_names[]) */
|
}; /* artilist[] (or artifact_names[]) */
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+1
-1
@@ -137,7 +137,7 @@ extern void init_artifacts(void);
|
|||||||
extern void save_artifacts(NHFILE *);
|
extern void save_artifacts(NHFILE *);
|
||||||
extern void restore_artifacts(NHFILE *);
|
extern void restore_artifacts(NHFILE *);
|
||||||
extern const char *artiname(int);
|
extern const char *artiname(int);
|
||||||
extern struct obj *mk_artifact(struct obj *, aligntyp);
|
extern struct obj *mk_artifact(struct obj *, aligntyp, uchar);
|
||||||
extern const char *artifact_name(const char *, short *, boolean) NONNULLARG1;
|
extern const char *artifact_name(const char *, short *, boolean) NONNULLARG1;
|
||||||
extern boolean exist_artifact(int, const char *) NONNULLPTRS;
|
extern boolean exist_artifact(int, const char *) NONNULLPTRS;
|
||||||
extern void artifact_exists(struct obj *, const char *, boolean, unsigned) ;
|
extern void artifact_exists(struct obj *, const char *, boolean, unsigned) ;
|
||||||
|
|||||||
+43
-10
@@ -142,13 +142,16 @@ artiname(int artinum)
|
|||||||
If no alignment is given, then 'otmp' is converted
|
If no alignment is given, then 'otmp' is converted
|
||||||
into an artifact of matching type, or returned as-is if that's not
|
into an artifact of matching type, or returned as-is if that's not
|
||||||
possible.
|
possible.
|
||||||
For the 2nd case, caller should use ``obj = mk_artifact(obj, A_NONE);''
|
For the 2nd case, caller should use ``obj = mk_artifact(obj, A_NONE, 99);''
|
||||||
for the 1st, ``obj = mk_artifact((struct obj *) 0, some_alignment);''.
|
For the 1st, ``obj = mk_artifact((struct obj *) 0, some_alignment, ...);''.
|
||||||
|
The max_giftvalue is the value of the sacrifice, for an artifact obtained
|
||||||
|
by sacrificing, or 99 otherwise.
|
||||||
*/
|
*/
|
||||||
struct obj *
|
struct obj *
|
||||||
mk_artifact(
|
mk_artifact(
|
||||||
struct obj *otmp, /* existing object; ignored if alignment specified */
|
struct obj *otmp, /* existing object; ignored if alignment specified */
|
||||||
aligntyp alignment) /* target alignment, or A_NONE */
|
aligntyp alignment, /* target alignment, or A_NONE */
|
||||||
|
uchar max_giftvalue) /* cap on generated giftvalue */
|
||||||
{
|
{
|
||||||
const struct artifact *a;
|
const struct artifact *a;
|
||||||
int m, n, altn;
|
int m, n, altn;
|
||||||
@@ -156,6 +159,7 @@ mk_artifact(
|
|||||||
short o_typ = (by_align || !otmp) ? 0 : otmp->otyp;
|
short o_typ = (by_align || !otmp) ? 0 : otmp->otyp;
|
||||||
boolean unique = !by_align && otmp && objects[o_typ].oc_unique;
|
boolean unique = !by_align && otmp && objects[o_typ].oc_unique;
|
||||||
short eligible[NROFARTIFACTS];
|
short eligible[NROFARTIFACTS];
|
||||||
|
xint16 skill_compatibility;
|
||||||
|
|
||||||
n = altn = 0; /* no candidates found yet */
|
n = altn = 0; /* no candidates found yet */
|
||||||
eligible[0] = 0; /* lint suppression */
|
eligible[0] = 0; /* lint suppression */
|
||||||
@@ -165,6 +169,8 @@ mk_artifact(
|
|||||||
continue;
|
continue;
|
||||||
if ((a->spfx & SPFX_NOGEN) || unique)
|
if ((a->spfx & SPFX_NOGEN) || unique)
|
||||||
continue;
|
continue;
|
||||||
|
if (a->gift_value > max_giftvalue)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (!by_align) {
|
if (!by_align) {
|
||||||
/* looking for a particular type of item; not producing a
|
/* looking for a particular type of item; not producing a
|
||||||
@@ -186,17 +192,33 @@ mk_artifact(
|
|||||||
n = 1;
|
n = 1;
|
||||||
break; /* skip all other candidates */
|
break; /* skip all other candidates */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* check if this is skill-compatible */
|
||||||
|
skill_compatibility = P_SKILLED;
|
||||||
|
if (objects[a->otyp].oc_class == WEAPON_CLASS) {
|
||||||
|
schar skill = objects[a->otyp].oc_skill;
|
||||||
|
if (skill < 0)
|
||||||
|
skill_compatibility = P_MAX_SKILL(-skill);
|
||||||
|
else
|
||||||
|
skill_compatibility = P_MAX_SKILL(skill);
|
||||||
|
}
|
||||||
|
|
||||||
/* found something to consider for random selection */
|
/* found something to consider for random selection */
|
||||||
if (a->alignment != A_NONE || u.ugifts > 0) {
|
if ((a->alignment != A_NONE || u.ugifts > 0 || !rn2(3)) &&
|
||||||
|
(!rn2(4) || skill_compatibility >= P_SKILLED ||
|
||||||
|
(skill_compatibility >= P_BASIC && rn2(2)))) {
|
||||||
/* right alignment, or non-aligned with at least 1
|
/* right alignment, or non-aligned with at least 1
|
||||||
previous gift bestowed, makes this one viable */
|
previous gift bestowed, makes this one viable;
|
||||||
|
unaligned artifacts are possible even as the first
|
||||||
|
gift, but less likely; if it's a bad weapon type
|
||||||
|
for the role that also makes it less likely */
|
||||||
eligible[n++] = m;
|
eligible[n++] = m;
|
||||||
} else {
|
} else {
|
||||||
/* non-aligned with no previous gifts;
|
/* if no candidates have been found yet, record
|
||||||
if no candidates have been found yet, record
|
|
||||||
this one as a[nother] fallback possibility in
|
this one as a[nother] fallback possibility in
|
||||||
case all aligned candidates have been used up
|
case all aligned candidates have been used up
|
||||||
(via wishing, naming, bones, random generation) */
|
(via wishing, naming, bones, random generation)
|
||||||
|
or failed the randomized compatibility checks */
|
||||||
if (!n)
|
if (!n)
|
||||||
eligible[altn++] = m;
|
eligible[altn++] = m;
|
||||||
/* [once a regular candidate is found, the list
|
/* [once a regular candidate is found, the list
|
||||||
@@ -215,9 +237,20 @@ mk_artifact(
|
|||||||
a = &artilist[m];
|
a = &artilist[m];
|
||||||
|
|
||||||
/* make an appropriate object if necessary, then christen it */
|
/* make an appropriate object if necessary, then christen it */
|
||||||
if (by_align)
|
if (by_align) {
|
||||||
|
int new_spe;
|
||||||
|
|
||||||
otmp = mksobj((int) a->otyp, TRUE, FALSE);
|
otmp = mksobj((int) a->otyp, TRUE, FALSE);
|
||||||
|
|
||||||
|
/* Adjust otmp->spe by a->gen_spe. (This is a no-op for
|
||||||
|
non-weapons, which always have a gen_spe of 0, and for many
|
||||||
|
weapons, too.) The result is clamped into the "normal" range to
|
||||||
|
prevent an outside chance of +12 artifacts generating. */
|
||||||
|
new_spe = (int)otmp->spe + a->gen_spe;
|
||||||
|
if (new_spe >= -10 && new_spe < 10)
|
||||||
|
otmp->spe = new_spe;
|
||||||
|
}
|
||||||
|
|
||||||
if (otmp) {
|
if (otmp) {
|
||||||
/* prevent erosion from generating */
|
/* prevent erosion from generating */
|
||||||
otmp->oeroded = otmp->oeroded2 = 0;
|
otmp->oeroded = otmp->oeroded2 = 0;
|
||||||
|
|||||||
+3
-3
@@ -880,7 +880,7 @@ mksobj_init(struct obj *otmp, boolean artif)
|
|||||||
otmp->opoisoned = 1;
|
otmp->opoisoned = 1;
|
||||||
|
|
||||||
if (artif && !rn2(20 + (10 * nartifact_exist())))
|
if (artif && !rn2(20 + (10 * nartifact_exist())))
|
||||||
otmp = mk_artifact(otmp, (aligntyp) A_NONE);
|
otmp = mk_artifact(otmp, (aligntyp) A_NONE, 99);
|
||||||
break;
|
break;
|
||||||
case FOOD_CLASS:
|
case FOOD_CLASS:
|
||||||
otmp->oeaten = 0;
|
otmp->oeaten = 0;
|
||||||
@@ -1084,7 +1084,7 @@ mksobj_init(struct obj *otmp, boolean artif)
|
|||||||
} else
|
} else
|
||||||
blessorcurse(otmp, 10);
|
blessorcurse(otmp, 10);
|
||||||
if (artif && !rn2(40 + (10 * nartifact_exist())))
|
if (artif && !rn2(40 + (10 * nartifact_exist())))
|
||||||
otmp = mk_artifact(otmp, (aligntyp) A_NONE);
|
otmp = mk_artifact(otmp, (aligntyp) A_NONE, 99);
|
||||||
/* simulate lacquered armor for samurai */
|
/* simulate lacquered armor for samurai */
|
||||||
if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL
|
if (Role_if(PM_SAMURAI) && otmp->otyp == SPLINT_MAIL
|
||||||
&& (svm.moves <= 1 || In_quest(&u.uz))) {
|
&& (svm.moves <= 1 || In_quest(&u.uz))) {
|
||||||
@@ -1230,7 +1230,7 @@ mksobj(int otyp, boolean init, boolean artif)
|
|||||||
|
|
||||||
/* unique objects may have an associated artifact entry */
|
/* unique objects may have an associated artifact entry */
|
||||||
if (objects[otyp].oc_unique && !otmp->oartifact)
|
if (objects[otyp].oc_unique && !otmp->oartifact)
|
||||||
otmp = mk_artifact(otmp, (aligntyp) A_NONE);
|
otmp = mk_artifact(otmp, (aligntyp) A_NONE, 99);
|
||||||
otmp->owt = weight(otmp);
|
otmp->owt = weight(otmp);
|
||||||
return otmp;
|
return otmp;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -262,7 +262,7 @@ mk_mplayer(struct permonst *ptr, coordxy x, coordxy y, boolean special)
|
|||||||
else if (!rn2(2))
|
else if (!rn2(2))
|
||||||
otmp->greased = 1;
|
otmp->greased = 1;
|
||||||
if (special && rn2(2))
|
if (special && rn2(2))
|
||||||
otmp = mk_artifact(otmp, A_NONE);
|
otmp = mk_artifact(otmp, A_NONE, 99);
|
||||||
/* usually increase stack size if stackable weapon */
|
/* usually increase stack size if stackable weapon */
|
||||||
if (objects[otmp->otyp].oc_merge && !otmp->oartifact
|
if (objects[otmp->otyp].oc_merge && !otmp->oartifact
|
||||||
&& monmightthrowwep(otmp))
|
&& monmightthrowwep(otmp))
|
||||||
|
|||||||
+16
-9
@@ -27,7 +27,7 @@ staticfn void offer_negative_valued(boolean, aligntyp);
|
|||||||
staticfn void offer_fake_amulet(struct obj *, boolean, aligntyp);
|
staticfn void offer_fake_amulet(struct obj *, boolean, aligntyp);
|
||||||
staticfn void offer_different_alignment_altar(struct obj *, aligntyp);
|
staticfn void offer_different_alignment_altar(struct obj *, aligntyp);
|
||||||
staticfn void sacrifice_your_race(struct obj *, boolean, aligntyp);
|
staticfn void sacrifice_your_race(struct obj *, boolean, aligntyp);
|
||||||
staticfn int bestow_artifact(void);
|
staticfn int bestow_artifact(uchar);
|
||||||
staticfn int sacrifice_value(struct obj *);
|
staticfn int sacrifice_value(struct obj *);
|
||||||
staticfn int eval_offering(struct obj *, aligntyp);
|
staticfn int eval_offering(struct obj *, aligntyp);
|
||||||
staticfn void offer_corpse(struct obj *, boolean, aligntyp);
|
staticfn void offer_corpse(struct obj *, boolean, aligntyp);
|
||||||
@@ -1777,17 +1777,24 @@ sacrifice_your_race(
|
|||||||
}
|
}
|
||||||
|
|
||||||
staticfn int
|
staticfn int
|
||||||
bestow_artifact(void)
|
bestow_artifact(uchar max_giftvalue)
|
||||||
{
|
{
|
||||||
int nartifacts = nartifact_exist();
|
int nartifacts = nartifact_exist();
|
||||||
|
boolean do_bestow = u.ulevel > 2 && u.uluck >= 0;
|
||||||
|
if (do_bestow) {
|
||||||
|
/* you were already in pretty good standing */
|
||||||
|
/* The player can gain an artifact */
|
||||||
|
/* The chance goes down as the number of artifacts goes up */
|
||||||
|
if (wizard)
|
||||||
|
do_bestow = y_n("Gift an artifact?");
|
||||||
|
else
|
||||||
|
do_bestow = !rn2(6 + (2 * u.ugifts * nartifacts));
|
||||||
|
}
|
||||||
|
|
||||||
/* you were already in pretty good standing */
|
if (do_bestow) {
|
||||||
/* The player can gain an artifact */
|
|
||||||
/* The chance goes down as the number of artifacts goes up */
|
|
||||||
if (u.ulevel > 2 && u.uluck >= 0
|
|
||||||
&& !rn2(10 + (2 * u.ugifts * nartifacts))) {
|
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
otmp = mk_artifact((struct obj *) 0, a_align(u.ux, u.uy));
|
otmp = mk_artifact((struct obj *) 0, a_align(u.ux, u.uy),
|
||||||
|
max_giftvalue);
|
||||||
if (otmp) {
|
if (otmp) {
|
||||||
char buf[BUFSZ];
|
char buf[BUFSZ];
|
||||||
|
|
||||||
@@ -2078,7 +2085,7 @@ offer_corpse(struct obj *otmp, boolean highaltar, aligntyp altaralign)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
int saved_luck = u.uluck;
|
int saved_luck = u.uluck;
|
||||||
if (bestow_artifact())
|
if (bestow_artifact(value))
|
||||||
return;
|
return;
|
||||||
change_luck((value * LUCKMAX) / (MAXVALUE * 2));
|
change_luck((value * LUCKMAX) / (MAXVALUE * 2));
|
||||||
if ((int) u.uluck < 0)
|
if ((int) u.uluck < 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user