suggestions. Note that divine robustness is no longer available from Zin, but the code for it is still in place, since it can be adopted later for Elyvilon.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@6839 c06c8d41-db1a-0410-9941-cceddc491573
BLEMEEWDXTMGHF35D2NYDKU6O2NCFOTRXDKDT6TISL3PJTKUALFAC
CN33TRD23Q3P2K5ZP7PZLMWM6ZXDMYM6OTCI65MRDVY335WMGBLAC
ZVVJ5GQMZIRWK27FULUKKJGRJHSALGZ7W5OYNGVTQMFU7QRVSXRAC
7LO3JOTJ23PUAA2WTKETVMSROEGEYXH5OMA52MJWOVF6AOUZ3KHQC
2CY5LRKEK4ZXBGZDFMALPW5BLHPOLZ7GV6RG75DQRUXI5J4EGNWQC
SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC
AROBKQGZEY7IBWUQ6XNGEJQJMI3XB7BXLMX5PHU3L6DWIATCH7EAC
DRQ6OBPWBA5MKPVQXELBHOWBN3I374QHD7OBTYSOEU3XQ2WBXUJQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
XPMFRLTXS5LA4TROB43JS7NZ4FB2JAQBZZMZWS7SHPMU4SKUIYTQC
MRNLVLPKGYRKAJ775ATOG5V6LYD3DTIKGWEUE7F6NGD6S3CNBIVQC
MPQIZUHUAHOF2CKNTLSYCGMR7FIC3EPA2RHZIY6JOQKAS6H6YY4AC
PEOV4EX5UATQWYQEVOUV2EHJ4JBCRVQ3BJXU655PXVFVEQNN2D2AC
CHBGJUUFNUCOGAIIWSZKHHNP5AMYXBO7PLFBID7C6HJ3YYU7CLWQC
JIUOMEDSR4FSHCVNCFOQBM4LFQRWEAID2EWRNZ2FIKZNBV3MCW7AC
CGYTZT5QWIEGYKUOLOK7MFXSLJKLYRZONER5ZCDZO5XYWSLG475QC
XTUKLNRQ6OB4SAJFCF7XT5A643QXGNMEW4YHZTOSSAKZAGHJALZAC
ZXYVKEDP7QYG66XFUCXXCKZXT7Z5OOEJWHICWOYAUZQ4SSLHIA4AC
IHDUCQLZCL74OXNV5ICHQCPQ6TDAHZBVGUTMLXHP432WJH5VOZWQC
PRQ3EYE6QDRMGWIPRON2NVNDCY5YBDHD2NURV5H5T4GYV5YHUOTQC
35NWNQBNLDOHPPHMYA2722IIFGAA57LUN5NOZPRUFZBD5EVCSYCAC
IT6JBMDXGN6X3F3W4ERVPFSURM4G7ZBSIBDMUXV5ZZXXSLM6RSAAC
OZ5D37MVA3M2COBXAFMD3IZAW55RVPQRQBNTH5HARFWU7SW4PARAC
HXAKQLE5VFM3TREGGSFH362HVJPZ2NE5JCQUTMKD5YBZCS4JTU4AC
4K7OPFNBESDPBBCGTGJCYWR32THYQKRRB3EAIK7IHEHN5XXAHYOQC
I5ECB3F77YUAWY4MVFU3PTBJUYYR4J76VWA6JY5PE5NR44QHXTWQC
UW7HW2UZEZ2ZNMZBX5HKHH22OJCSG2QRJJNZ6JGZQGENENGY7VBAC
NJFYSNTX33RAPYMVYJYGSCHOE7AWYX4ZG6ZRJZBDVDQWTANTM2QQC
BFPWM2MSF5HSN5UZXNEB5FR22P536UR24E3WXY5IIHC2SDIPOWSAC
KJ7BAVTDVVETEXDWUUDPDRCSX5DWRU2QOTYCUOICFA7CJPAGNVCAC
2R4Q7C5ATEAJ5JXJZQSDPFFGLOU36TTV6DMGM47BY5CUQTD5KTKAC
HVYJMQL4JNEWML77XJEPCO3WWMGJDY2POGH4FEYCAZUL7VHVEDXQC
FEXFEKY3QAJ4M2RIJB3SOV65ECDY6M6K5DQJ7FEOXNAGQDEYVKUAC
SMFI5G2UUW6I5GQYEYJNSCS4HGA5HFCHD45VBD4EW5NNNBDJIMOQC
IRFZWY73JMTEINZXEDDGGAGJ5PAMBF7FTZGVOPV7WI6MYGPK6I2QC
GQLLYETI5KID6MXQ6YJ5TZJYN5V3QDFOUQIKBVDYGVARNWBCMOSAC
ZCSYP2AFLY5QD4NAZSLAO33QYTVITJVRAJMFOE33CZZRVCWYXHNQC
RLUTEWVTO3LPFWOQHZWW5AC6VK6APFPVYFZRMAQ22LGOQ77GDPKAC
FGFWHE6BFX4EKW2XO2SGYJSML2PCNYTBWHVS3J3BXOMXFPO5PKRQC
J3IUDNIRXUTU5MDEICM6FM4IA7ZC37ZO5WF6QYMTTUOMV6R3VLTQC
C56DCU3P3IMGE6GC4X55ZCUCFY45KQWKPWPCD5UBKH3QMELDOTLAC
HGH6TXJX5PZ6UWUX5CO2BRFCMG6EQY5EWI4YLYLBHTEHE2HEJBEAC
76LKB66IWIPTE75HR2T4B75YFRVZ3PVRPX5WTRPNTOOP3SLAQWFAC
3S5MXRGHKBYOT4Q2BXMARYJH4PEPTAH5CRV5Z23RBE7VQLO2Y57QC
43KP5J4MOLV6KO7EBNPHZWWDSDG6EXLA5KEZLI5UZMI2C5ZF5A2AC
KHHAE5ZK7ITEZVMMUKYROKECLE2RU5ZU5OQ4Z4XSRQXE2R65O67AC
UVGFF3QPZKZNMWFDDANQRBTVOROTA4TZFXGYDPV4GQXZKHZY2EXAC
L44U7EP4MJJ635JA5PHPQGYZJ5XQ2GFZIICKIMD62244HMGPRFNQC
JDBTF7NKDHWDTAX5LRBQ75A5JBNELFITVYQ6KOGW5XM2SGW33STQC
OEHJJ5X5CBOHTXISZLJHVLCAPH77RYSVKKBGW3US2GGXZMZJ5CEQC
23PFLB2E4QHL5SF3Q2YV5FXRH6MFHENEU2ACVC572ZCYDXCBZVQAC
SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC
LC2XZTUD56PLARIGBTDXDPJIYJNMJU446GFDGLRIFD2I4F66L6TAC
DK362IHKSDADMUPD35NOTKM4WESQM37KG2PNOJRV2FGELDWULYPQC
KKEPQAZMWQFWPQ4P4KT5PWG2YFPG7H4JHL5K7USVHQ3Y6L4NWURQC
}
void vitalisation_chain(int amount)
{
if (amount <= 0)
return;
const int old_value = you.duration[DUR_VITALISATION_CHAIN];
you.duration[DUR_VITALISATION_CHAIN] += amount;
if (you.duration[DUR_VITALISATION_CHAIN] > 30)
you.duration[DUR_VITALISATION_CHAIN] = 30;
if (old_value == 0)
mpr("Zin amplifies your power of vitalisation!", MSGCH_DURATION);
void reduce_vitalisation_chain(int amount)
{
if (you.duration[DUR_VITALISATION_CHAIN] == 0 || amount <= 0)
return;
you.duration[DUR_VITALISATION_CHAIN] -= amount;
if (you.duration[DUR_VITALISATION_CHAIN] <= 0)
{
you.duration[DUR_VITALISATION_CHAIN] = 0;
mpr("Your power of vitalisation returns to normal.", MSGCH_DURATION);
}
}
const int step_max_chain = 6;
const int type_max_chain = 4;
static int step;
static int step_max;
static int type;
static int hp_amt;
static int mp_amt;
static bool need_chain;
// If vitalisation chaining is turned off, start from the beginning.
if (you.duration[DUR_VITALISATION_CHAIN] == 0)
{
step = 0;
step_max = std::min(pow, step_max_chain);
type = random2(type_max_chain * 3 / 2);
hp_amt = 3;
mp_amt = 1;
need_chain = false;
}
success = true;
inc_hp(hp_amt, false);
inc_mp(mp_amt, false);
hp_amt *= 2;
mp_amt *= 2;
need_chain =
(you.hp < you.hp_max
|| you.magic_points < you.max_magic_points);
break;
}
need_chain = false;
step = 0;
type = 1;
// Deliberate fall through, resetting the vitalisation chaining
// indicator and the step counter.
case 1:
switch (step)
{
case 0:
case 1:
case 2:
// Restore stats.
if (you.strength < you.max_strength
|| you.intel < you.max_intel
|| you.dex < you.max_dex)
switch (random2(6))
success = true;
restore_stat(STAT_STRENGTH, step + 1, true);
restore_stat(STAT_INTELLIGENCE, step + 1, true);
restore_stat(STAT_DEXTERITY, step + 1, true);
need_chain =
(you.strength < you.max_strength
|| you.intel < you.max_intel
|| you.dex < you.max_dex);
break;
}
step = 3;
// Deliberate fall through.
if (step >= step_max)
case 0:
if (you.disease)
{
success = true;
you.disease = 0;
}
default:
break;
}
if (success)
break;
need_chain = false;
step = 0;
type = 2;
// Deliberate fall through, resetting the vitalisation chaining
// indicator and the step counter.
case 2:
// Remove negative afflictions.
switch (step)
{
// Remove confusion and poisoning.
case 0:
if (you.duration[DUR_CONF] || you.duration[DUR_POISONING])
{
success = true;
you.duration[DUR_CONF] = 0;
you.duration[DUR_POISONING] = 0;
need_chain = false;
case 1:
if (you.rotting)
{
success = true;
you.rotting = 0;
}
// Remove sickness and rotting.
case 1:
if (you.disease || you.rotting)
{
success = true;
you.disease = 0;
you.rotting = 0;
need_chain = false;
case 3:
if (you.duration[DUR_PARALYSIS])
{
success = true;
you.duration[DUR_PARALYSIS] = 0;
}
// Restore rotted HP.
case 2:
if (player_rotted())
{
success = true;
unrot_hp(3 + random2(9));
need_chain = false;
case 5:
if (you.duration[DUR_PETRIFIED])
{
success = true;
you.duration[DUR_PETRIFIED] = 0;
}
if (success)
break;
need_chain = false;
step = 0;
type = 3;
// Deliberate fall through, resetting the vitalisation chaining
// indicator and the step counter.
case 3:
while (!success);
}
// Restore stats.
else if (you.strength < you.max_strength
|| you.intel < you.max_intel
|| you.dex < you.max_dex)
// Divine stamina.
case 0:
case 2:
case 4:
if ((estep == 0 || you.duration[DUR_VITALISATION_CHAIN] > 0)
&& ((you.attribute[ATTR_DIVINE_STAMINA] + 1) / 2) == estep
&& ((player_mutation_level(MUT_STRONG) + 1) / 5) < (3 - estep)
&& ((player_mutation_level(MUT_CLEVER) + 1) / 5) < (3 - estep)
&& ((player_mutation_level(MUT_AGILE) + 1) / 5) < (3 - estep))
switch (random2(3))
success = true;
mprf(MSGCH_DURATION, "Zin %s divine stamina.",
(estep == 0) ? "grants you" :
(estep == 1) ? "strengthens your"
: "maximises your");
const int stamina_amt = step + 1;
you.attribute[ATTR_DIVINE_STAMINA] += stamina_amt;
you.duration[DUR_DIVINE_STAMINA] +=
(estep == 0) ? (you.skills[SK_INVOCATIONS] * 2) :
(estep == 1) ? (you.skills[SK_INVOCATIONS])
: (you.skills[SK_INVOCATIONS] / 2);
modify_stat(STAT_STRENGTH, stamina_amt, true, "");
modify_stat(STAT_INTELLIGENCE, stamina_amt, true, "");
modify_stat(STAT_DEXTERITY, stamina_amt, true, "");
// Keep vitalisation chaining on if divine stamina can
// be increased two vitalisation attempts from now, or
// if divine robustness can be increased one
// vitalisation attempt from now.
need_chain =
(((player_mutation_level(MUT_STRONG) + 1) / 5) < (2 - estep)
&& ((player_mutation_level(MUT_CLEVER) + 1) / 5) < (2 - estep)
&& ((player_mutation_level(MUT_AGILE) + 1) / 5) < (2 - estep))
|| (player_mutation_level(MUT_ROBUST) < (3 - estep));
case 0:
if (you.strength < you.max_strength)
{
success = true;
restore_stat(STAT_STRENGTH, 0, true);
}
}
step++;
goto stamina_robustness;
// Deliberate fall through.
// Divine robustness.
case 1:
case 3:
case 5:
if ((estep == 0 || you.duration[DUR_VITALISATION_CHAIN] > 0)
&& you.attribute[ATTR_DIVINE_ROBUSTNESS] == estep
&& player_mutation_level(MUT_ROBUST) < (3 - estep))
{
success = true;
mprf(MSGCH_DURATION, "Zin %s divine robustness.",
(estep == 0) ? "grants you" :
(estep == 1) ? "strengthens your"
: "maximises your");
you.attribute[ATTR_DIVINE_ROBUSTNESS]++;
you.duration[DUR_DIVINE_ROBUSTNESS] +=
(estep == 0) ? (you.skills[SK_INVOCATIONS] * 2) :
(estep == 1) ? (you.skills[SK_INVOCATIONS])
: (you.skills[SK_INVOCATIONS] / 2);
const int old_hp_max = you.hp_max;
calc_hp();
set_hp(you.hp * you.hp_max / old_hp_max, false);
// Keep vitalisation chaining on if divine robustness
// can be increased two vitalisation attempts from now,
// or if divine stamina can be increased one
// vitalisation attempt from now.
need_chain =
(player_mutation_level(MUT_ROBUST) < (2 - estep))
|| (((player_mutation_level(MUT_STRONG) + 1) / 5) < (3 - estep)
&& ((player_mutation_level(MUT_CLEVER) + 1) / 5) < (3 - estep)
&& ((player_mutation_level(MUT_AGILE) + 1) / 5) < (3 - estep));
case 1:
if (you.intel < you.max_intel)
{
success = true;
restore_stat(STAT_INTELLIGENCE, 0, true);
}
break;
case 2:
if (you.dex < you.max_dex)
{
success = true;
restore_stat(STAT_DEXTERITY, 0, true);
}
step++;
goto stamina_robustness;
// Deliberate fall through.
default:
break;
need_chain = false;
step = 0;
type = 4;
// Deliberate fall through, resetting the vitalisation chaining
// indicator and the step counter.
}
const int stamina_amt = 3;
you.attribute[ATTR_DIVINE_STAMINA] += stamina_amt;
you.duration[DUR_DIVINE_STAMINA]
= 35 + (you.skills[SK_INVOCATIONS]*5)/3;
default:
// Do nothing.
break;
modify_stat(STAT_STRENGTH, stamina_amt, true, "");
modify_stat(STAT_INTELLIGENCE, stamina_amt, true, "");
modify_stat(STAT_DEXTERITY, stamina_amt, true, "");
}
mprf("You feel %s %s.", (step == 0) ? "only nominally" :
(step == 1) ? "very slightly" :
(step == 2) ? "slightly" :
(step == 3) ? "somewhat" :
(step == 4) ? "appropriately"
: "impressively",
(type == 0) ? "invigorated" :
(type == 1) ? "renewed" :
(type == 2) ? "better"
: "powerful");
// If vitalisation has succeeded, pay the extended piety cost,
// based on how far the step counter has advanced.
int loss_amt = step + 1 + (random2(3) - 1);
if (loss_amt > 0)
lose_piety(loss_amt);
// Increment the step counter.
step++;
mprf("You feel %s.", (type == 0) ? "better" :
(type == 1) ? "renewed"
: "powerful");
// Whether vitalisation has succeeded or failed, pay the minimum
// piety cost.
lose_piety(2);
// If there's not enough piety left to vitalise again, turn off
// vitalisation chaining.
if (you.piety < piety_breakpoint(1))
need_chain = false;
// If vitalisation has succeeded, it hasn't succeeded as far as
// possible, and vitalisation chaining is needed, turn on
// vitalisation chaining for several turns.
if (success && step < step_max && need_chain)
vitalisation_chain(6);
// Otherwise, turn off vitalisation chaining.
else
reduce_vitalisation_chain(30);
return (success) ? (step + 1) : 0;
return (success);
if (you.duration[DUR_VITALISATION_CHAIN])
{
mpr("Your power of vitalisation disappears!");
you.duration[DUR_VITALISATION_CHAIN] = 0;
}
if (you.duration[DUR_DIVINE_ROBUSTNESS])
remove_divine_robustness();
if (you.duration[DUR_VITALISATION_CHAIN])
{
mpr("Your power of vitalisation disappears!");
you.duration[DUR_VITALISATION_CHAIN] = 0;
}
if (you.duration[DUR_DIVINE_ROBUSTNESS])
remove_divine_robustness();
If Zin is most pleased with you, you can Vitalise yourself. This will
restore Health, Magic, attribute points, or unrot you. In case none of
these is necessary, you gain temporary boosts to your attributes
instead. It is possible to Vitalise several times in succession for
greater effect.
If Zin is most pleased with you, you can Vitalise yourself. This will
remove a negative affliction from you, or restore one of your
attributes. In case neither of these is necessary, it will give you
temporary boosts to your attributes instead.
ABFLAG_PIETY = 0x00000004, // ability has its own piety (ie vitalise)
ABFLAG_PAIN = 0x00000008, // ability must hurt player (ie torment)
ABFLAG_EXHAUSTION = 0x00000010, // fails if you.exhausted
ABFLAG_INSTANT = 0x00000020, // doesn't take time to use
ABFLAG_PERMANENT_HP = 0x00000040, // costs permanent HPs
ABFLAG_PERMANENT_MP = 0x00000080, // costs permanent MPs
ABFLAG_CONF_OK = 0x00000100 // can use even if confused
ABFLAG_PAIN = 0x00000004, // ability must hurt player (ie torment)
ABFLAG_EXHAUSTION = 0x00000008, // fails if you.exhausted
ABFLAG_INSTANT = 0x00000010, // doesn't take time to use
ABFLAG_PERMANENT_HP = 0x00000020, // costs permanent HPs
ABFLAG_PERMANENT_MP = 0x00000040, // costs permanent MPs
ABFLAG_CONF_OK = 0x00000080 // can use even if confused
{
int result = cast_vitalisation(1 + (you.skills[SK_INVOCATIONS] / 4));
if (result > 0)
exercise(SK_INVOCATIONS, 2 + random2(result));
if (cast_vitalisation())
exercise(SK_INVOCATIONS, (coinflip() ? 3 : 2));