as bad as the old horror.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1425 c06c8d41-db1a-0410-9941-cceddc491573
WXSNNK2RXP3DQFAEQGQUZJHFWXJC7ZKG2WURZGL566UDM4YXFSWQC
DAVTHXRQBYQKWHKUKJVJ5EJXIFGVWMEHINLM3JE4FMV6AAYIBOVAC
RB3ZDZXUZ3KVU5C4MFWTQB4J3PCQ5IQS4UVUBRS3TLSPFKBWNFDAC
KW43PGXTTM57DXUGGBQXJ5G5OYYIY3WB76TXIKL2ZCIJGH7GH4LAC
ZBTD5R4OOQ5D4W6ZRK2XEGLI3AWI37Z2G5X2EQ6IYPXDYKCKWMFAC
X2FMEN4E345XD26Z2X7JMJ7VGHOGCGIELMHQRE2ITLVNQACP3NOQC
QKGDOYIYKE6B36ION5O2DRW65DWWPZMYNWJVH7LJJ7FPGGM2MYAQC
5ASC3STDYCNLZFEBN6UTMUCGDETHBR2OCBZCF5VIAZ5RRWLOTDYQC
K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC
RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC
YCL3W2PFE6ILTGBFODCSXNPDIA46KVSZP2TI7HDMYAOEJT65RIEAC
7NDXS36TE7QVXTXJWMYSVG5UHCCLPIO4VL6NXFGTDK3ZNKE3A2IAC
SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC
AVSWNOP23Z2QCLQGXFDZV7TI4RC3XSXHIX2HDXFHXGKDEZSSIGJQC
GMYJ4XEEKZASQWMXQZUME5VYCDBRODO7UJJUEZSVZBMSFVBFLK2AC
IJ6KN5MQLEB7DR7NW2AYQNCVBV5IUKECUSECUMEJWOBRNJBAXHCQC
JW2KRJHES33W7UTWZ6NDO4TLMK4EFU4HKZXBWR2UJOMPCCOTR4CQC
// print out targeted spell:
mprf("%c - %s", input_1, get_ability_name_by_index( index_1 ) );
mpr( "Adjust to which letter?", MSGCH_PROMPT );
if (isalpha( nthing ) || nthing == ESCAPE)
keyin = nthing;
else
{
mesclr( true );
goto query;
}
}
if (keyin == ESCAPE)
{
adjust_spells_cleanup(needs_redraw);
canned_msg( MSG_OK );
return;
}
int input_2 = keyin;
if (!isalpha( input_2 ))
{
adjust_spells_cleanup(needs_redraw);
mpr("What?");
return;
int tmp = you.ability_letter_table[index_2];
you.ability_letter_table[index_2] = you.ability_letter_table[index_1];
you.ability_letter_table[index_1] = tmp;
ability_type tmp = you.ability_letter_table[index2];
you.ability_letter_table[index2] = you.ability_letter_table[index1];
you.ability_letter_table[index1] = tmp;
}
// Note: the input_2/index_1 and input_1/index_2 here is intentional.
// This is because nothing actually moves until generate_abilities is
// called again... fortunately that has to be done everytime because
// that's the silly way this system currently works. -- bwr
mprf("%c - %s", input_2, get_ability_name_by_index( index_1 ) );
if (you.ability_letter_table[index_1] != ABIL_NON_ABILITY)
mprf("%c - %s", input_1, get_ability_name_by_index( index_2 ) );
} // end adjust_ability()
const std::string make_cost_description( const struct ability_def &abil );
const char* ability_name(ability_type ability);
const std::string make_cost_description( ability_type ability );
std::vector<const char*> get_ability_names();
int choose_ability_menu(const std::vector<talent>& talents);
bool activate_ability( void ); // handles all special abilities now
char show_abilities( void );
bool generate_abilities( bool check_conf );
bool activate_ability();
std::vector<talent> your_talents( bool check_confused );
for (int i = 0; i < 52; ++i)
if (Curr_abil[i].which != ABIL_NON_ABILITY)
{
if (have_any)
text += ", ";
text += get_ability_name_by_index(i);
have_any = true;
}
for (unsigned int i = 0; i < talents.size(); ++i)
{
if (i)
text += ", ";
text += get_ability_def(talents[i].which).name;
}
std::vector<const char *> abils;
if (generate_abilities(false))
ASSERT(ability != ABIL_NON_ABILITY);
talent result;
result.which = ability;
int failure = 0;
bool perfect = false; // is perfect
bool invoc = false;
if (check_confused)
return (abils);
// Look through the table to see if there's a preference, else
// find a new empty slot for this ability. -- bwr
const int index = find_ability_slot( ability );
if ( index != -1 )
result.hotkey = index_to_letter(index);
else
result.hotkey = 0; // means 'find later on'
switch (ability)
{
// begin spell abilities
case ABIL_DELAYED_FIREBALL:
case ABIL_MUMMY_RESTORATION:
perfect = true;
failure = 0;
break;
// begin species abilities - some are mutagenic, too {dlb}
case ABIL_GLAMOUR:
failure = 50 - (you.experience_level * 2);
break;
case ABIL_SPIT_POISON:
failure = ((you.species == SP_NAGA) ? 20 : 40)
- 10 * you.mutation[MUT_SPIT_POISON]
- you.experience_level;
break;
case ABIL_EVOKE_MAPPING:
failure = 30 - you.skills[SK_EVOCATIONS];
break;
case ABIL_MAPPING:
failure = 40 - 10 * you.mutation[MUT_MAPPING] - you.experience_level;
break;
case ABIL_BREATHE_FIRE:
failure = ((you.species == SP_RED_DRACONIAN) ? 30 : 50)
- 10 * you.mutation[MUT_BREATHE_FLAMES]
- you.experience_level;
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
failure -= 20;
break;
case ABIL_BREATHE_FROST:
case ABIL_BREATHE_POISON:
case ABIL_SPIT_ACID:
case ABIL_BREATHE_LIGHTNING:
case ABIL_BREATHE_POWER:
case ABIL_BREATHE_STICKY_FLAME:
failure = 30 - you.experience_level;
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
failure -= 20;
break;
case ABIL_BREATHE_STEAM:
failure = 20 - you.experience_level;
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
failure -= 20;
break;
case ABIL_FLY: // this is for kenku {dlb}
failure = 45 - (3 * you.experience_level);
break;
case ABIL_FLY_II: // this is for draconians {dlb}
failure = 45 - (you.experience_level + you.strength);
break;
// end species abilties (some mutagenic)
// begin demonic powers {dlb}
case ABIL_THROW_FLAME:
case ABIL_THROW_FROST:
failure = 10 - you.experience_level;
break;
case ABIL_SUMMON_MINOR_DEMON:
failure = 27 - you.experience_level;
break;
case ABIL_CHANNELING:
case ABIL_BOLT_OF_DRAINING:
failure = 30 - you.experience_level;
break;
case ABIL_CONTROL_DEMON:
failure = 35 - you.experience_level;
break;
case ABIL_SUMMON_DEMONS:
failure = 40 - you.experience_level;
break;
case ABIL_TO_PANDEMONIUM:
failure = 57 - (you.experience_level * 2);
break;
case ABIL_HELLFIRE:
case ABIL_RAISE_DEAD:
failure = 50 - you.experience_level;
break;
case ABIL_TORMENT:
failure = 60 - you.experience_level;
break;
case ABIL_BLINK:
failure = 30 - (10 * you.mutation[MUT_BLINK]) - you.experience_level;
break;
case ABIL_TELEPORTATION:
failure = ((you.mutation[MUT_TELEPORT_AT_WILL] > 1) ? 30 : 50)
- you.experience_level;
break;
// end demonic powers {dlb}
// begin transformation abilities {dlb}
case ABIL_END_TRANSFORMATION:
perfect = true;
failure = 0;
break;
case ABIL_BREATHE_HELLFIRE:
failure = 32 - you.experience_level;
break;
// end transformation abilities {dlb}
//
// begin item abilities - some possibly mutagenic {dlb}
case ABIL_EVOKE_TURN_INVISIBLE:
case ABIL_EVOKE_TELEPORTATION:
failure = 60 - 2 * you.skills[SK_EVOCATIONS];
break;
case ABIL_EVOKE_TURN_VISIBLE:
case ABIL_EVOKE_STOP_LEVITATING:
perfect = true;
failure = 0;
break;
case ABIL_EVOKE_LEVITATE:
case ABIL_EVOKE_BLINK:
failure = 40 - 2 * you.skills[SK_EVOCATIONS];
break;
case ABIL_EVOKE_BERSERK:
failure = 50 - 2 * you.skills[SK_EVOCATIONS];
if (you.species == SP_TROLL)
failure -= 30;
else if (player_genus(GENPC_DWARVEN) || you.species == SP_HILL_ORC
|| you.species == SP_OGRE)
{
failure -= 10;
}
break;
// end item abilities - some possibly mutagenic {dlb}
// begin invocations {dlb}
case ABIL_ELYVILON_PURIFICATION:
invoc = true;
failure = 20 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_ZIN_REPEL_UNDEAD:
case ABIL_TSO_REPEL_UNDEAD:
case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
case ABIL_OKAWARU_MIGHT:
case ABIL_ELYVILON_LESSER_HEALING:
invoc = true;
failure = 30 - (you.piety / 20) - (6 * you.skills[SK_INVOCATIONS]);
break;
// These three are Trog abilities... Invocations means nothing -- bwr
case ABIL_TROG_BERSERK: // piety >= 30
invoc = true;
failure = 30 - you.piety; // starts at 0%
break;
case ABIL_TROG_MIGHT: // piety >= 50
invoc = true;
failure = 80 - you.piety; // starts at 30%
break;
case ABIL_TROG_HASTE_SELF: // piety >= 100
invoc = true;
failure = 160 - you.piety; // starts at 60%
break;
case ABIL_YRED_ANIMATE_CORPSE:
invoc = true;
failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_ZIN_HEALING:
case ABIL_TSO_SMITING:
case ABIL_OKAWARU_HEALING:
case ABIL_MAKHLEB_MINOR_DESTRUCTION:
case ABIL_SIF_MUNA_FORGET_SPELL:
case ABIL_KIKU_ENSLAVE_UNDEAD:
case ABIL_YRED_ANIMATE_DEAD:
case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
case ABIL_ELYVILON_HEALING:
invoc = true;
failure = 40 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_SIF_MUNA_CHANNEL_ENERGY:
invoc = true;
failure = 40 - you.intel - you.skills[SK_INVOCATIONS];
break;
case ABIL_YRED_RECALL_UNDEAD:
invoc = true;
failure = 50 - (you.piety / 20) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ZIN_PESTILENCE:
case ABIL_TSO_ANNIHILATE_UNDEAD:
invoc = true;
failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
case ABIL_YRED_DRAIN_LIFE:
invoc = true;
failure = 60 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ZIN_HOLY_WORD:
case ABIL_TSO_CLEANSING_FLAME:
case ABIL_ELYVILON_RESTORATION:
case ABIL_YRED_CONTROL_UNDEAD:
case ABIL_OKAWARU_HASTE:
case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
invoc = true;
failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ZIN_SUMMON_GUARDIAN:
case ABIL_TSO_SUMMON_DAEVA:
case ABIL_KIKU_INVOKE_DEATH:
case ABIL_ELYVILON_GREATER_HEALING:
invoc = true;
failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
//jmf: following for to-be-created gods
case ABIL_CHARM_SNAKE:
invoc = true;
failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_TRAN_SERPENT_OF_HELL:
invoc = true;
failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ROTTING:
invoc = true;
failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_TORMENT_II:
invoc = true;
failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_RENOUNCE_RELIGION:
invoc = true;
perfect = true;
failure = 0;
break;
// end invocations {dlb}
default:
failure = -1;
break;
}
// Perfect abilities are things like "renounce religion", which
// shouldn't have a failure rate ever. -- bwr
if (failure <= 0 && !perfect)
failure = 1;
if (failure > 100)
failure = 100;
result.fail = failure;
result.is_invocation = invoc;
return result;
/*
Activates a menu which gives player access to all of their non-spell
special abilities - e.g. nagas' spit poison, or the Invocations you get
from worshipping. Generated dynamically - the function checks to see which
abilities you have every time.
*/
bool activate_ability(void)
/*************************/
std::vector<const char*> get_ability_names()
mpr("You're too confused!");
return (false);
}
bool need_redraw = false;
bool need_prompt = true;
bool need_getch = true;
for (;;)
{
if (need_redraw)
talents = your_talents(true);
if ( talents.empty() )
// no turning back now... {dlb}
const struct ability_def abil = get_ability_def(Curr_abil[abil_used].which);
const ability_def& abil = get_ability_def(tal.which);
// check that we can afford to pay the costs
if (!enough_mp( abil.mp_cost, false ))
return (false);
return (true);
} // end activate_ability()
int choose_ability_menu(const std::vector<talent>& talents)
{
Menu abil_menu(MF_SINGLESELECT | MF_ANYPRINTABLE);
abil_menu.set_highlighter(NULL);
abil_menu.set_title(new MenuEntry(" Ability Cost Success"));
gotoxy(1, num_lines);
cprintf("-more-");
ki = getch();
if (ki == ESCAPE)
{
return (ESCAPE);
}
if (ki >= 'A' && ki <= 'z')
{
return (ki);
}
if (ki == 0)
ki = getch();
lines = 0;
clrscr();
gotoxy(1, 1);
anything = 0;
MenuEntry* me = new MenuEntry(describe_talent(talents[i]),
MEL_ITEM, 1, talents[i].hotkey);
me->data = reinterpret_cast<void*>(numbers+i);
abil_menu.add_entry(me);
if (Curr_abil[loopy].which != ABIL_NON_ABILITY
&& (do_invoke == Curr_abil[loopy].is_invocation))
{
anything++;
if (lines > 0)
cprintf(EOL);
lines++;
const struct ability_def abil = get_ability_def( Curr_abil[loopy].which );
cprintf( " %c - %s", index_to_letter(loopy), abil.name );
// Output costs:
gotoxy( 35, wherey() );
std::string cost_str = make_cost_description( abil );
if (cost_str.length() > 24)
cost_str = cost_str.substr( 0, 24 );
cprintf( "%s", cost_str.c_str() );
gotoxy(60, wherey());
cprintf( "%s", failure_rate_to_string(Curr_abil[loopy].fail));
gotoxy(70, wherey());
} // end if conditional
} // end "for loopy"
}
ki = getch();
if (ki >= 'A' && ki <= 'z')
{
return (ki);
}
if (ki == 0)
ki = getch();
return (ki);
return -1;
}
else
{
ASSERT(sel.size() == 1);
ASSERT(sel[0]->hotkeys.size() == 1);
return (*(reinterpret_cast<int*>(sel[0]->data)));
bool generate_abilities( bool check_confused )
/*****************************/
std::ostringstream desc;
desc << std::left
<< std::setw(30) << ability_name(tal.which)
<< std::setw(24) << make_cost_description(tal.which)
<< std::setw(10) << failure_rate_to_string(tal.fail);
return desc.str();
}
static void add_talent(std::vector<talent>& vec, const ability_type ability,
bool check_confused)
// fill array of structs with "empty" values {dlb}:
for (loopy = 0; loopy < 52; loopy++)
{
Curr_abil[loopy].which = ABIL_NON_ABILITY;
Curr_abil[loopy].fail = 100;
Curr_abil[loopy].is_invocation = false;
}
std::vector<talent> your_talents( bool check_confused )
{
std::vector<talent> talents;
if (Curr_abil[loopy].which != ABIL_NON_ABILITY)
return (true);
}
// skip preassigned hotkeys
if ( talents[i].hotkey != 0 )
continue;
// try to find a free hotkey for i, starting from Z
for ( int k = 51; k >= 0; ++k )
{
const int kkey = index_to_letter(k);
bool good_key = true;
return (false);
} // end generate_abilities()
// check that it doesn't conflict with other hotkeys
for ( unsigned int j = 0; j < talents.size(); ++j )
{
if ( talents[j].hotkey == kkey )
{
good_key = false;
break;
}
}
if ( good_key )
{
talents[i].hotkey = k;
break;
}
}
// In theory, we could be left with an unreachable ability
// here (if you have 53 or more abilities simultaneously.)
}
return talents;
}
// returns index to Curr_abil, -1 on failure
static int find_ability_slot( int which_ability )
/***********************************************/
// returns an index (0-51) if successful, -1 if you should
// just use the next one
static int find_ability_slot( ability_type which_ability )
// if we skipped over a-e to reserve them, try them now
if (Options.lowercase_invocations && slot == 52)
{
for (slot = 5; slot >= 0; slot--)
{
if (you.ability_letter_table[slot] == ABIL_NON_ABILITY)
break;
}
}
// All letters are assigned, check Curr_abil and try to steal a letter
if (slot == 52)
{
// backwards, to protect the low lettered slots from replacement
for (slot = 51; slot >= 0; slot--)
{
if (Curr_abil[slot].which == ABIL_NON_ABILITY)
break;
}
// no slots at all == no hope of adding
if (slot < 0)
return (-1);
}
// this ability now takes over this slot
you.ability_letter_table[slot] = which_ability;
}
// skip over a-e if player prefers them for invocations
const int startpoint = (Options.lowercase_invocations ? 5 : 0);
return (slot);
}
static bool insert_ability( int which_ability, bool check_conf )
/**********************************************/
{
ASSERT( which_ability != ABIL_NON_ABILITY );
int failure = 0;
bool perfect = false; // is perfect
bool invoc = false;
// Look through the table to see if there's a preference, else
// find a new empty slot for this ability. -- bwr
const int slot = find_ability_slot( which_ability );
if (slot == -1)
return (false);
if (check_conf)
for (int slot = startpoint; slot < 52; slot++)
// begin spell abilities
case ABIL_DELAYED_FIREBALL:
case ABIL_MUMMY_RESTORATION:
perfect = true;
failure = 0;
break;
// begin species abilities - some are mutagenic, too {dlb}
case ABIL_GLAMOUR:
failure = 50 - (you.experience_level * 2);
break;
case ABIL_SPIT_POISON:
failure = ((you.species == SP_NAGA) ? 20 : 40)
- 10 * you.mutation[MUT_SPIT_POISON]
- you.experience_level;
break;
case ABIL_EVOKE_MAPPING:
failure = 30 - you.skills[SK_EVOCATIONS];
break;
case ABIL_MAPPING:
failure = 40 - 10 * you.mutation[MUT_MAPPING] - you.experience_level;
break;
case ABIL_BREATHE_FIRE:
failure = ((you.species == SP_RED_DRACONIAN) ? 30 : 50)
- 10 * you.mutation[MUT_BREATHE_FLAMES]
- you.experience_level;
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
failure -= 20;
break;
case ABIL_BREATHE_FROST:
case ABIL_BREATHE_POISON:
case ABIL_SPIT_ACID:
case ABIL_BREATHE_LIGHTNING:
case ABIL_BREATHE_POWER:
case ABIL_BREATHE_STICKY_FLAME:
failure = 30 - you.experience_level;
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
failure -= 20;
break;
case ABIL_BREATHE_STEAM:
failure = 20 - you.experience_level;
if (you.attribute[ATTR_TRANSFORMATION] == TRAN_DRAGON)
failure -= 20;
break;
case ABIL_FLY: // this is for kenku {dlb}
failure = 45 - (3 * you.experience_level);
break;
case ABIL_FLY_II: // this is for draconians {dlb}
failure = 45 - (you.experience_level + you.strength);
break;
// end species abilties (some mutagenic)
// begin demonic powers {dlb}
case ABIL_THROW_FLAME:
case ABIL_THROW_FROST:
failure = 10 - you.experience_level;
break;
case ABIL_SUMMON_MINOR_DEMON:
failure = 27 - you.experience_level;
break;
case ABIL_CHANNELING:
case ABIL_BOLT_OF_DRAINING:
failure = 30 - you.experience_level;
break;
case ABIL_CONTROL_DEMON:
failure = 35 - you.experience_level;
break;
case ABIL_SUMMON_DEMONS:
failure = 40 - you.experience_level;
break;
case ABIL_TO_PANDEMONIUM:
failure = 57 - (you.experience_level * 2);
break;
case ABIL_HELLFIRE:
case ABIL_RAISE_DEAD:
failure = 50 - you.experience_level;
break;
case ABIL_TORMENT:
failure = 60 - you.experience_level;
break;
case ABIL_BLINK:
failure = 30 - (10 * you.mutation[MUT_BLINK]) - you.experience_level;
break;
case ABIL_TELEPORTATION:
failure = ((you.mutation[MUT_TELEPORT_AT_WILL] > 1) ? 30 : 50)
- you.experience_level;
break;
// end demonic powers {dlb}
// begin transformation abilities {dlb}
case ABIL_END_TRANSFORMATION:
perfect = true;
failure = 0;
break;
case ABIL_BREATHE_HELLFIRE:
failure = 32 - you.experience_level;
break;
// end transformation abilities {dlb}
//
// begin item abilities - some possibly mutagenic {dlb}
case ABIL_EVOKE_TURN_INVISIBLE:
case ABIL_EVOKE_TELEPORTATION:
failure = 60 - 2 * you.skills[SK_EVOCATIONS];
break;
case ABIL_EVOKE_TURN_VISIBLE:
case ABIL_EVOKE_STOP_LEVITATING:
perfect = true;
failure = 0;
break;
case ABIL_EVOKE_LEVITATE:
case ABIL_EVOKE_BLINK:
failure = 40 - 2 * you.skills[SK_EVOCATIONS];
break;
case ABIL_EVOKE_BERSERK:
failure = 50 - 2 * you.skills[SK_EVOCATIONS];
if (you.species == SP_TROLL)
failure -= 30;
else if (player_genus(GENPC_DWARVEN) || you.species == SP_HILL_ORC
|| you.species == SP_OGRE)
{
failure -= 10;
}
break;
// end item abilities - some possibly mutagenic {dlb}
// begin invocations {dlb}
case ABIL_ELYVILON_PURIFICATION:
invoc = true;
failure = 20 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_ZIN_REPEL_UNDEAD:
case ABIL_TSO_REPEL_UNDEAD:
case ABIL_KIKU_RECALL_UNDEAD_SLAVES:
case ABIL_OKAWARU_MIGHT:
case ABIL_ELYVILON_LESSER_HEALING:
invoc = true;
failure = 30 - (you.piety / 20) - (6 * you.skills[SK_INVOCATIONS]);
break;
// These three are Trog abilities... Invocations means nothing -- bwr
case ABIL_TROG_BERSERK: // piety >= 30
invoc = true;
failure = 30 - you.piety; // starts at 0%
break;
case ABIL_TROG_MIGHT: // piety >= 50
invoc = true;
failure = 80 - you.piety; // starts at 30%
break;
case ABIL_TROG_HASTE_SELF: // piety >= 100
invoc = true;
failure = 160 - you.piety; // starts at 60%
break;
case ABIL_YRED_ANIMATE_CORPSE:
invoc = true;
failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_ZIN_HEALING:
case ABIL_TSO_SMITING:
case ABIL_OKAWARU_HEALING:
case ABIL_MAKHLEB_MINOR_DESTRUCTION:
case ABIL_SIF_MUNA_FORGET_SPELL:
case ABIL_KIKU_ENSLAVE_UNDEAD:
case ABIL_YRED_ANIMATE_DEAD:
case ABIL_MAKHLEB_LESSER_SERVANT_OF_MAKHLEB:
case ABIL_ELYVILON_HEALING:
invoc = true;
failure = 40 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_SIF_MUNA_CHANNEL_ENERGY:
invoc = true;
failure = 40 - you.intel - you.skills[SK_INVOCATIONS];
break;
case ABIL_YRED_RECALL_UNDEAD:
invoc = true;
failure = 50 - (you.piety / 20) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ZIN_PESTILENCE:
case ABIL_TSO_ANNIHILATE_UNDEAD:
invoc = true;
failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_MAKHLEB_MAJOR_DESTRUCTION:
case ABIL_YRED_DRAIN_LIFE:
invoc = true;
failure = 60 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ZIN_HOLY_WORD:
case ABIL_TSO_CLEANSING_FLAME:
case ABIL_ELYVILON_RESTORATION:
case ABIL_YRED_CONTROL_UNDEAD:
case ABIL_OKAWARU_HASTE:
case ABIL_MAKHLEB_GREATER_SERVANT_OF_MAKHLEB:
invoc = true;
failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ZIN_SUMMON_GUARDIAN:
case ABIL_TSO_SUMMON_DAEVA:
case ABIL_KIKU_INVOKE_DEATH:
case ABIL_ELYVILON_GREATER_HEALING:
invoc = true;
failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
//jmf: following for to-be-created gods
case ABIL_CHARM_SNAKE:
invoc = true;
failure = 40 - (you.piety / 20) - (3 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_TRAN_SERPENT_OF_HELL:
invoc = true;
failure = 80 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_ROTTING:
invoc = true;
failure = 60 - (you.piety / 20) - (5 * you.skills[SK_INVOCATIONS]);
break;
case ABIL_TORMENT_II:
invoc = true;
failure = 70 - (you.piety / 25) - (you.skills[SK_INVOCATIONS] * 4);
break;
case ABIL_RENOUNCE_RELIGION:
invoc = true;
perfect = true;
failure = 0;
break;
// end invocations {dlb}
default:
failure = -1;
break;
if (you.ability_letter_table[slot] == ABIL_NON_ABILITY)
return slot;