Overhaul of priest donations
The old code had two main problems: a) it was very difficult for unspoiled players to figure out how it worked (because donating too much got you a bad result, and the exact amount you needed depended on magic numbers that weren't stated in game, and because you had to hide your visible gold to get a good result); b) for players who knew the mechanics, it was somewhat exploitable and also somewhat tedious to make use of (due to needing to hide visible gold before donating). This change preserves the spirit of the previous code whilst making things more transparent for new players and less tedious for existing players: the donation amounts for the various effects are still roughly the same (but randomized), but the amounts you need to donate for clairvoyance and for protection are explicitly stated (and as before, the alignment reset is done by donating an unnecessarily large amount and isn't explicitly stated as an option). If you have a lot of visible gold, you still need to donate a sizeable proportion of it to get a useful effect, but now you get a larger reward to compensate for the larger donation (to the extent that doing this gives comparable results to doing it as a series of small donations, removing the incentive to hide your gold before donating). There's also something here for those players who like to squeeze every last point of optimality out of a game: the "obvious" donation strategy gives decent results, but players who are really willing to dig into the mechanics may be able to find a way to get slightly better results on average (which if I've balanced this correctly, will lead to a very long and complicated spoiler). One other change is that this is now based on your peak rather than current level, to fix an exploit in which the character was drained down to level 1 to donate a very large amount of gold (improving by 20 AC points) and then immediately restored back to the previous experience level using a blessed potion of restore ablity. This breaks save compatibility, but is being pushed together with other save-breaking changes to avoid the need for multiple bumps to EDITLEVEL.
This commit is contained in:
@@ -1582,6 +1582,9 @@ healers may get tiny damage increase when attacking with knives
|
||||
allow rogues to also backstab sleeping or paralyzed monsters
|
||||
rogues cannot backstab monsters that have no backside
|
||||
give experience if opening Schroedinger's Box causes death of the cat inside
|
||||
priest donation amounts are explicitly stated, randomized slightly, based on
|
||||
peak rather than current level, and allow for bulk donations (buying
|
||||
larger amounts of clairvoyance/protection) if you have a lot of gold
|
||||
|
||||
|
||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||
|
||||
@@ -1545,7 +1545,7 @@ extern int monster_census(boolean);
|
||||
extern int msummon(struct monst *);
|
||||
extern void summon_minion(aligntyp, boolean);
|
||||
extern int demon_talk(struct monst *) NONNULLARG1;
|
||||
extern long bribe(struct monst *) NONNULLARG1;
|
||||
extern long bribe(struct monst *, const char *) NONNULLARG12;
|
||||
extern int dprince(aligntyp);
|
||||
extern int dlord(aligntyp);
|
||||
extern int llord(void);
|
||||
|
||||
@@ -98,6 +98,7 @@ struct epri {
|
||||
schar shroom; /* index in rooms */
|
||||
coord shrpos; /* position of shrine */
|
||||
d_level shrlevel; /* level (& dungeon) of shrine */
|
||||
unsigned cheapskate_count; /* number of cheapskate donations */
|
||||
long intone_time, /* used to limit verbosity +*/
|
||||
enter_time, /*+ of temple entry messages */
|
||||
hostile_time, /* forbidding feeling */
|
||||
|
||||
@@ -332,7 +332,8 @@ demon_talk(struct monst *mtmp)
|
||||
else if (canseemon(mtmp))
|
||||
pline("%s seems to be demanding something.", Amonnam(mtmp));
|
||||
offer = 0L;
|
||||
if (!Deaf && ((offer = bribe(mtmp)) >= demand)) {
|
||||
if (!Deaf &&
|
||||
((offer = bribe(mtmp, "How much will you offer?")) >= demand)) {
|
||||
pline("%s vanishes, laughing about cowardly mortals.",
|
||||
Amonnam(mtmp));
|
||||
} else if (offer > 0L
|
||||
@@ -357,13 +358,13 @@ demon_talk(struct monst *mtmp)
|
||||
}
|
||||
|
||||
long
|
||||
bribe(struct monst *mtmp)
|
||||
bribe(struct monst *mtmp, const char *prompt)
|
||||
{
|
||||
char buf[BUFSZ] = DUMMY;
|
||||
long offer;
|
||||
long umoney = money_cnt(gi.invent);
|
||||
|
||||
getlin("How much will you offer?", buf);
|
||||
getlin(prompt, buf);
|
||||
if (sscanf(buf, "%ld", &offer) != 1)
|
||||
offer = 0L;
|
||||
|
||||
|
||||
74
src/priest.c
74
src/priest.c
@@ -559,6 +559,8 @@ priest_talk(struct monst *priest)
|
||||
{
|
||||
boolean coaligned = p_coaligned(priest);
|
||||
boolean strayed = (u.ualign.record < 0);
|
||||
unsigned *cheapskate = NULL;
|
||||
if (EPRI(priest)) cheapskate = &EPRI(priest)->cheapskate_count;
|
||||
|
||||
/*
|
||||
* Note: we won't be called if hero is Deaf [since dochat() will
|
||||
@@ -625,53 +627,87 @@ priest_talk(struct monst *priest)
|
||||
pline("%s is not interested.", Monnam(priest));
|
||||
return;
|
||||
} else {
|
||||
/* there's now some randomization in how much you need to donate, but
|
||||
you are given suggested donation values that will guarantee
|
||||
clairvoyance and protection respectively; with more gold visible
|
||||
you need to donate more but get a greater effect; and if you
|
||||
cheapskate out to rerandomize the donation amounts they will be
|
||||
higher next time */
|
||||
long offer;
|
||||
long suggested = (u.ulevelpeak ? u.ulevelpeak : 1 ) *
|
||||
rn1(101, 150 + (cheapskate ? *cheapskate : 0) * 40);
|
||||
long quan = money_cnt(gi.invent) / (suggested * 3);
|
||||
char buf[BUFSZ];
|
||||
|
||||
pline("%s asks you for a contribution for the temple.",
|
||||
Monnam(priest));
|
||||
if ((offer = bribe(priest)) == 0) {
|
||||
if (quan < 1)
|
||||
quan = 1;
|
||||
|
||||
Sprintf(buf, "How much will you offer (suggested: %ld or %ld)?",
|
||||
suggested * quan, suggested * quan * 2);
|
||||
|
||||
if (flags.debug)
|
||||
pline("%s asks you for a contribution for the temple (base %ld).",
|
||||
Monnam(priest), suggested);
|
||||
else
|
||||
pline("%s asks you for a contribution for the temple.",
|
||||
Monnam(priest));
|
||||
if ((offer = bribe(priest, buf)) == 0) {
|
||||
SetVoice(priest, 0, 80, 0);
|
||||
verbalize("Thou shalt regret thine action!");
|
||||
if (coaligned)
|
||||
adjalign(-1);
|
||||
} else if (offer < (u.ulevel * 200)) {
|
||||
if (cheapskate) ++*cheapskate;
|
||||
} else if (offer < suggested * quan) {
|
||||
if (money_cnt(gi.invent) > (offer * 2L)) {
|
||||
SetVoice(priest, 0, 80, 0);
|
||||
verbalize("Cheapskate.");
|
||||
if (cheapskate) ++*cheapskate;
|
||||
} else {
|
||||
SetVoice(priest, 0, 80, 0);
|
||||
verbalize("I thank thee for thy contribution.");
|
||||
/* give player some token */
|
||||
exercise(A_WIS, TRUE);
|
||||
}
|
||||
} else if (offer < (u.ulevel * 400)) {
|
||||
} else if (offer < suggested * quan * 2) {
|
||||
SetVoice(priest, 0, 80, 0);
|
||||
verbalize("Thou art indeed a pious individual.");
|
||||
if (money_cnt(gi.invent) < (offer * 2L)) {
|
||||
if (coaligned && u.ualign.record <= ALGN_SINNED)
|
||||
adjalign(1);
|
||||
verbalize("I bestow upon thee a blessing.");
|
||||
incr_itimeout(&HClairvoyant, rn1(500, 500));
|
||||
}
|
||||
} else if (offer < (u.ulevel * 600)
|
||||
/* u.ublessed is only active when Protection is
|
||||
enabled via something other than worn gear
|
||||
(theft by gremlin clears the intrinsic but not
|
||||
its former magnitude, making it recoverable) */
|
||||
&& (!(HProtection & INTRINSIC)
|
||||
|| (u.ublessed < 20
|
||||
&& (u.ublessed < 9 || !rn2(u.ublessed))))) {
|
||||
SetVoice(priest, 0, 80, 0);
|
||||
verbalize("Thou hast been rewarded for thy devotion.");
|
||||
verbalize("I bestow upon thee a blessing.");
|
||||
incr_itimeout(&HClairvoyant, rn1(500 * offer / suggested,
|
||||
500 * offer / suggested));
|
||||
} else if (offer < suggested * quan * 3) {
|
||||
int orig_ublessed = u.ublessed;
|
||||
|
||||
/* u.ublessed is only active when Protection is enabled via
|
||||
something other than worn gear (theft by gremlin clears the
|
||||
intrinsic but not its former magnitude, making it
|
||||
recoverable) */
|
||||
if (!(HProtection & INTRINSIC)) {
|
||||
HProtection |= FROMOUTSIDE;
|
||||
orig_ublessed = -1; /* force "rewarded" message */
|
||||
}
|
||||
|
||||
for (; offer >= (2 * suggested); offer -= (2 * suggested)) {
|
||||
if (!u.ublessed)
|
||||
u.ublessed = rn1(3, 2);
|
||||
} else
|
||||
u.ublessed++;
|
||||
else if (u.ublessed < 20 &&
|
||||
(u.ublessed < 9 || !rn2(u.ublessed)))
|
||||
u.ublessed++;
|
||||
}
|
||||
SetVoice(priest, 0, 80, 0);
|
||||
if (u.ublessed > orig_ublessed) {
|
||||
verbalize("Thou hast been rewarded for thy devotion.");
|
||||
} else {
|
||||
verbalize("Thy selfless generosity is deeply appreciated.");
|
||||
}
|
||||
} else {
|
||||
SetVoice(priest, 0, 80, 0);
|
||||
verbalize("Thy selfless generosity is deeply appreciated.");
|
||||
/* money_cnt check is preserved for futureproofing but probably
|
||||
can't fail in the current code */
|
||||
if (money_cnt(gi.invent) < (offer * 2L) && coaligned) {
|
||||
if (strayed && (svm.moves - u.ucleansed) > 5000L) {
|
||||
u.ualign.record = 0; /* cleanse thee */
|
||||
|
||||
Reference in New Issue
Block a user