spell1.cc
static bool _can_pacify_monster(const monsters *mon, const int healed)
{
if (you.religion != GOD_ELYVILON)
return (false);
if (healed < 1)
return (false);
// I was thinking of jellies when I wrote this, but maybe we shouldn't
// exclude zombies and such... (jpeg)
if (mons_intel(mon) <= I_PLANT) // no self-awareness
return (false);
const mon_holy_type holiness = mons_holiness(mon);
if (holiness != MH_HOLY
&& holiness != MH_NATURAL
&& holiness != MH_UNDEAD
&& holiness != MH_DEMONIC)
{
return (false);
}
if (mons_is_stationary(mon)) // not able to leave the level
return (false);
if (mons_is_sleeping(mon)) // not aware of what is happening
return (false);
const int factor = (mons_intel(mon) <= I_ANIMAL) ? 3 : // animals
(is_player_same_species(mon->type)) ? 2 // same species
: 1; // other
int divisor = 3;
if (holiness == MH_HOLY)
divisor--;
else if (holiness == MH_UNDEAD)
divisor++;
else if (holiness == MH_DEMONIC)
divisor += 2;
const int random_factor = random2((you.skills[SK_INVOCATIONS] + 1) *
healed / divisor);
#ifdef DEBUG_DIAGNOSTICS
mprf(MSGCH_DIAGNOSTICS,
"pacifying %s? max hp: %d, factor: %d, Inv: %d, healed: %d, rnd: %d",
mon->name(DESC_PLAIN).c_str(), mon->max_hit_points, factor,
you.skills[SK_INVOCATIONS], healed, random_factor);
#endif
if (mon->max_hit_points < factor * random_factor)
return (true);
return (false);
}
// Returns: 1 -- success, 0 -- failure, -1 -- cancel
static int _healing_spell(int healed, bool divine_ability,
const coord_def& where, bool not_self,
targ_mode_type mode)
{
ASSERT(healed >= 1);
bolt beam;
dist spd;
if (where.origin())
{
spd.isValid = spell_direction(spd, beam, DIR_TARGET,
mode != TARG_NUM_MODES ? mode :
you.religion == GOD_ELYVILON ?
TARG_ANY : TARG_FRIEND,
LOS_RADIUS,
false, true, true, "Heal whom?");
}
else
{
spd.target = where;
spd.isValid = in_bounds(spd.target);
}
if (!spd.isValid)
return (-1);
if (spd.target == you.pos())
{
if (not_self)
{
mpr("You can only heal others!");
return (-1);
}
mpr("You are healed.");
inc_hp(healed, false);
return (1);
}
monsters* monster = monster_at(spd.target);
if (!monster)
{
mpr("There isn't anything there!");
// This isn't a cancel, to avoid leaking invisible monster
// locations.
return (0);
}
const bool can_pacify = _can_pacify_monster(monster, healed);
const bool is_hostile = _mons_hostile(monster);
// Don't divinely heal a monster you can't pacify.
if (divine_ability
&& you.religion == GOD_ELYVILON
&& !can_pacify)
{
canned_msg(MSG_NOTHING_HAPPENS);
return (0);
}
bool did_something = false;
if (you.religion == GOD_ELYVILON
&& can_pacify && is_hostile)
{
did_something = true;
const bool is_holy = mons_is_holy(monster);
const bool is_summoned = mons_is_summoned(monster);
int pgain = 0;
if (!is_holy && !is_summoned && you.piety < MAX_PIETY)
{
pgain = random2(1 + random2(monster->max_hit_points /
(2 + you.piety / 20)));
}
if (pgain > 0)
simple_god_message(" approves of your offer of peace.");
else
simple_god_message(" supports your offer of peace.");
if (is_holy)
good_god_holy_attitude_change(monster);
else
{
simple_monster_message(monster, " turns neutral.");
mons_pacify(monster);
// Give a small piety return.
if (pgain > 0)
gain_piety(pgain);
}
}
if (heal_monster(monster, healed, false))
{
did_something = true;
mprf("You heal %s.", monster->name(DESC_NOCAP_THE).c_str());
if (monster->hit_points == monster->max_hit_points)
simple_monster_message(monster, " is completely healed.");
else
print_wounds(monster);
if (you.religion == GOD_ELYVILON && !is_hostile)
{
int pgain = 0;
if (one_chance_in(8) && you.piety < MAX_PIETY)
pgain = 1;
if (pgain > 0)
{
simple_god_message(" approves of your healing of a fellow "
"creature.");
}
else
{
simple_god_message(" appreciates your healing of a fellow "
"creature.");
}
// Give a small piety return.
if (pgain > 0)
gain_piety(pgain);
}
}
if (!did_something)
{
canned_msg(MSG_NOTHING_HAPPENS);
return (0);
}
return (1);
}
// Returns: 1 -- success, 0 -- failure, -1 -- cancel
int cast_healing(int pow, bool divine_ability, const coord_def& where,
bool not_self, targ_mode_type mode)
{
pow = std::min(50, pow);
return (_healing_spell(pow + roll_dice(2, pow) - 2, divine_ability, where,
not_self, mode));
}
void remove_divine_vigour()
{
mpr("Your divine vigour fades away.", MSGCH_DURATION);
you.duration[DUR_DIVINE_VIGOUR] = 0;
you.attribute[ATTR_DIVINE_VIGOUR] = 0;
calc_hp();
calc_mp();
}
bool cast_divine_vigour()
{
bool success = false;
if (!you.duration[DUR_DIVINE_VIGOUR])
{
mprf("%s grants you divine vigour.",
god_name(you.religion).c_str());
const int vigour_amt = 1 + (you.skills[SK_INVOCATIONS]/6);
const int old_hp_max = you.hp_max;
const int old_mp_max = you.max_magic_points;
you.attribute[ATTR_DIVINE_VIGOUR] = vigour_amt;
you.duration[DUR_DIVINE_VIGOUR]
= 40 + (you.skills[SK_INVOCATIONS]*5)/2;
calc_hp();
inc_hp(you.hp_max - old_hp_max, false);
calc_mp();
inc_mp(you.max_magic_points - old_mp_max, false);
success = true;
}
else
canned_msg(MSG_NOTHING_HAPPENS);
return (success);
}
abl-show.cc
// Elyvilon
{ ABIL_ELYVILON_DESTROY_WEAPONS, "Destroy Weapons",
0, 0, 0, 0, ABFLAG_NONE },
{ ABIL_ELYVILON_LESSER_HEALING_SELF, "Lesser Self-Healing",
1, 0, 100, generic_cost::range(0, 1), ABFLAG_CONF_OK },
{ ABIL_ELYVILON_LESSER_HEALING_OTHERS, "Lesser Healing",
1, 0, 100, 0, ABFLAG_CONF_OK },
{ ABIL_ELYVILON_PURIFICATION, "Purification", 2, 0, 150, 1,
ABFLAG_CONF_OK },
{ ABIL_ELYVILON_GREATER_HEALING_SELF, "Greater Self-Healing",
2, 0, 250, 2, ABFLAG_CONF_OK },
{ ABIL_ELYVILON_GREATER_HEALING_OTHERS, "Greater Healing",
2, 0, 250, 2, ABFLAG_CONF_OK },
{ ABIL_ELYVILON_RESTORATION, "Restoration", 3, 0, 400, 3, ABFLAG_CONF_OK },
{ ABIL_ELYVILON_DIVINE_VIGOUR, "Divine Vigour", 0, 0, 600, 6,
ABFLAG_CONF_OK },
case ABIL_ELYVILON_LESSER_HEALING_SELF:
case ABIL_ELYVILON_LESSER_HEALING_OTHERS:
{
const bool self = (abil.ability == ABIL_ELYVILON_LESSER_HEALING_SELF);
if (cast_healing(3 + (you.skills[SK_INVOCATIONS] / 6), true,
self ? you.pos() : coord_def(0, 0), !self,
self ? TARG_NUM_MODES : TARG_HOSTILE) < 0)
{
return (false);
}
exercise(SK_INVOCATIONS, 1);
break;
}
case ABIL_ELYVILON_PURIFICATION:
purification();
exercise(SK_INVOCATIONS, 2 + random2(3));
break;
case ABIL_ELYVILON_GREATER_HEALING_SELF:
case ABIL_ELYVILON_GREATER_HEALING_OTHERS:
{
const bool self = (abil.ability == ABIL_ELYVILON_GREATER_HEALING_SELF);
if (cast_healing(10 + (you.skills[SK_INVOCATIONS] / 3), true,
self ? you.pos() : coord_def(0, 0), !self,
self ? TARG_NUM_MODES : TARG_HOSTILE) < 0)
{
return (false);
}
exercise(SK_INVOCATIONS, 3 + random2(5));
break;
}
case ABIL_ELYVILON_RESTORATION:
restore_stat(STAT_ALL, 0, false);
unrot_hp(100);
exercise(SK_INVOCATIONS, 4 + random2(6));
break;
case ABIL_ELYVILON_DIVINE_VIGOUR:
if (!cast_divine_vigour())
return (false);
exercise(SK_INVOCATIONS, 6 + random2(10));
break;
player.cc
int get_real_hp(bool trans, bool rotted)
{
int hitp;
hitp = (you.base_hp - 5000) + (you.base_hp2 - 5000);
hitp += (you.experience_level * you.skills[SK_FIGHTING]) / 5;
// Being berserk makes you resistant to damage. I don't know why.
if (trans && you.duration[DUR_BERSERKER])
hitp *= 2;
if (trans)
{
// Some transformations give you extra hp.
switch (you.attribute[ATTR_TRANSFORMATION])
{
case TRAN_STATUE:
hitp *= 15;
hitp /= 10;
break;
case TRAN_ICE_BEAST:
hitp *= 12;
hitp /= 10;
break;
case TRAN_DRAGON:
hitp *= 16;
hitp /= 10;
break;
}
}
if (rotted)
hitp += player_rotted();
// Frail and robust mutations, and divine vigour.
hitp *= 10 + player_mutation_level(MUT_ROBUST)
+ you.attribute[ATTR_DIVINE_VIGOUR]
- player_mutation_level(MUT_FRAIL);
hitp /= 10;
return (hitp);
}