git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8465 c06c8d41-db1a-0410-9941-cceddc491573
H2OHWQKMHL66CPVJGJL35RY7EIZB74SZTGOLDJDSCG5WVEVPIIUAC
SOHQG56QTJOSEJ7VPVGDMXEWES4HEUGA4G3JDWQ2RZJBZQJVBHGQC
AA3I6WU2SPJUPKRIPGXCLU4EZOV4QELVVZ7EIAW3H73GES5DSFXQC
O4ZFDG3AEV3K4NPGCCLB7DXUH5CBETKP5FBKLCIET7JNTNDX5DUAC
MASPOPOXDKPY7B7LBMJW3WY4JUM4723RA6SXBB4KOK2ZDNKXLLWQC
45CWQUPQHKUFUJ4MVL5K3KCVCCKLY2Z7RZWZ53UT723RV5STPSRAC
26JV5AK6S3VRZQTX7RV65QV26JCLJ2P7VSCJTNCYLKJRZ6HOC6ZQC
KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC
FYSQ7HXDIKXZXDGYVKZMODW7HYQQLRZO52Q2HVM3PYBD37UT5B4AC
ERS7DYNAVCC7QUVG5FXJJRONYESLZU22CQGKCA5HLLLG6DMXYRLQC
RDOOG5LBE5TCTFYCKJIB7TGGTRFX4HBLMJZYXS5TCFWNCU3QII5QC
64HB7VYSYHQEN5UP7OYJ5GSVA2XMDSLLH647UPWE5NSFF3AVZSSQC
22YVHM74WBJNJE4PA5CBEUTDWM6FAGGGILI26A4LXAURX55TNRKAC
LUD5XPFLSYPJOYZG6DDV4C5WIQUGZPE7YV6AR75ENCAIISD3LZWQC
TRBDS4IKHBASW2CTAQ2YHMBMBMRB6QEBQ4ZE7GRSR3U2VJXA7TJQC
DP6XLMKLDC42SWISM7WKLJFTJTRZ3BKTRS7DWUQWLLP3DR4UUGZAC
2HG3XZSSPWPPEAPBGO7PBXSJOGJWXIU6UIGEWZZAG54OMM5HQXUQC
VO5CYD7Z4FYFDT6DGVBX6RT3PHLRSUJA6TWV3GPYVE7QCSJ3JEAAC
TPO6FNMPNUSWH4NCKO3VLYNAADEPSAXLUITCCACLZZSY53PKA62QC
U5QVBQESPTUIYTYVA2VU254NO5MTJA5SYMXMQ4SG2LPWMDNGCDPAC
PHBACPMH3F34GODHVDKNCMXWU373RJQGVTDLBFCCDLLWDXVYOLTAC
GYOKKBVTZ6HRW2NYC3EMGSB6ULBX24L5DLDZNEP2F6UTA4KPU3CAC
HCVH2CWL32UD66O6Z7ZYDUASWN3RF5TW6FSWURGMD7MELKB772FAC
5WHLQTLOJRJ67M4KAJZURHMNQLYHBW4XHQFBXV2LUQ4W6YKTOXVAC
M2GU6BVT6WPLE7WHBUSAOQNKWGX74JBVOJZYPUVSFHNHQLO2TMTQC
4LYEUWWWOR7IEPIZZKPE6RGDRNVRRPOSJDUUAUYFJEN4B65MNTZAC
FIYBXLWALQINNQTHG2KNDUUTAQAZRDDLXW2XOVSKDKBADJ3XCJ4AC
7RDIBNLUIBTAYOJXJ5Q3DOW3MKKYXBAA3Q4G4QE74KJL23NW6C7AC
QEPTJOPJFKTXH27KOHY7DMQSMTXWAM57OPL3Y7WYE4X2OFMZE5IAC
TO3JMTZO6ETZWBXPA75JLCFD7ML546WXBRLWHPKL44ZIQ2H5HW6QC
KVTA7IUBD2O7ZEUU5T5VP7D3XVLFLYICXUPP5WCPAODBXKK4DNNQC
GN333G64BJJSMYTTXVADZ6IPA3CC3ALVZ6TFGBFYYTED5HYM2MFQC
NIJDQAJEWQIYKPDWIXYCCT4JIWVE6CWJ3J3K4N5PPGHWENGNZZXQC
EXYOAOND4VQ76OFAAGCPVIFGIZIF6BQH6S263QZRQIWAZWEDAYNAC
UWHZCQPPWGEJXWES63STKGH4L65LTS35RQUXUL7CCCROQBLHHNZQC
bool done = false;
bool rc = false;
potion_type pot =
static_cast<potion_type>(
random_choose(POT_HEALING, POT_HEAL_WOUNDS, POT_SPEED,
POT_MIGHT, POT_INVISIBILITY, POT_BERSERK_RAGE,
POT_EXPERIENCE, -1));
if (pot == POT_EXPERIENCE && !one_chance_in(6))
pot = POT_BERSERK_RAGE;
if (pot != POT_BERSERK_RAGE || you.can_go_berserk(false))
{
god_speaks(GOD_XOM, _get_xom_speech("potion effect").c_str());
// Don't make the player berserk if there's no danger.
if (tension > 0 && x_chance_in_y(2, sever))
static bool _xom_confuse_monsters(int sever)
{
bool rc = false;
monsters *monster;
for (unsigned i = 0; i < MAX_MONSTERS; ++i)
potion_type pot =
static_cast<potion_type>(
random_choose(POT_HEALING, POT_HEAL_WOUNDS, POT_SPEED,
POT_MIGHT, POT_INVISIBILITY, POT_BERSERK_RAGE,
POT_EXPERIENCE, -1));
if (pot == POT_EXPERIENCE && !one_chance_in(6))
pot = POT_BERSERK_RAGE;
monster = &menv[i];
god_speaks(GOD_XOM, _get_xom_speech("potion effect").c_str());
if (pot == POT_BERSERK_RAGE)
you.berserk_penalty = NO_BERSERK_PENALTY;
continue;
}
done = true;
}
else if (x_chance_in_y(4, sever))
{
monsters *monster;
for (unsigned i = 0; i < MAX_MONSTERS; ++i)
{
monster = &menv[i];
if (monster->type == -1 || !mons_near(monster)
|| mons_wont_attack(monster)
|| !mons_class_is_confusable(monster->type)
|| one_chance_in(20))
{
continue;
}
static bool _xom_send_allies(int sever)
{
bool rc = false;
const int numdemons =
std::min(random2(random2(random2(sever+1)+1)+1)+2, 16);
int numdifferent = 0;
if (monster->add_ench(mon_enchant(ENCH_CONFUSION, 0, KC_FRIENDLY, random2(sever))))
{
if (!done)
god_speaks(GOD_XOM, _get_xom_speech("confusion").c_str());
// If we have a mix of demons and non-demons, there's a chance
// that one or both of the factions may be hostile.
int hostiletype = random_choose_weighted(3, 0, // both friendly
4, 1, // one hostile
4, 2, // other hostile
1, 3, // both hostile
0);
simple_monster_message(monster, " looks rather confused.");
done = true;
}
}
}
// It's pointless to send in help if there's no danger.
else if (tension > 0 && x_chance_in_y(5, sever))
{
// FIXME: Can we clean up this ugliness, please?
const int numdemons =
std::min(random2(random2(random2(sever+1)+1)+1)+2, 16);
int numdifferent = 0;
std::vector<bool> is_demonic(numdemons, false);
std::vector<int> summons(numdemons);
// If we have a mix of demons and non-demons, there's a chance
// that one or both of the factions may be hostile.
int hostiletype = random_choose_weighted(3, 0, // both friendly
4, 1, // one hostile
4, 2, // other hostile
1, 3, // both hostile
0);
int num_actually_summoned = 0;
summons[i] =
create_monster(
mgen_data(monster, BEH_FRIENDLY,
3, MON_SUMM_AID,
you.pos(), you.pet_target,
MG_FORCE_BEH, GOD_XOM));
if (num_actually_summoned)
{
const bool only_holy = (numdifferent == num_actually_summoned);
const bool only_demonic = (numdifferent == 0);
if (summons[i] != -1)
success = true;
if (only_holy)
{
god_speaks(GOD_XOM,
_get_xom_speech("multiple holy summons").c_str());
}
else if (only_demonic)
{
god_speaks(GOD_XOM,
_get_xom_speech("multiple summons").c_str());
}
else
{
god_speaks(GOD_XOM,
_get_xom_speech("multiple mixed summons").c_str());
if (success)
// If we have only non-demons, there's a chance that they
// may be hostile.
if (only_holy && one_chance_in(4))
hostiletype = 2;
// If we have only demons, they'll always be friendly.
else if (only_demonic)
hostiletype = 0;
for (int i = 0; i < numdemons; ++i)
if (numdifferent == numdemons)
god_speaks(GOD_XOM, _get_xom_speech("multiple holy summons").c_str());
else if (numdifferent > 0)
god_speaks(GOD_XOM, _get_xom_speech("multiple mixed summons").c_str());
else
god_speaks(GOD_XOM, _get_xom_speech("multiple summons").c_str());
if (summons[i] == -1)
continue;
// If we have only non-demons, there's a chance that they
// may be hostile.
if (numdifferent == numdemons && one_chance_in(4))
hostiletype = 2;
// If we have only demons, they'll always be friendly.
else if (numdifferent == 0)
hostiletype = 0;
monsters *mon = &menv[summons[i]];
monsters *mon = &menv[summons[i]];
if (hostiletype != 0)
// Mark factions hostile as appropriate.
if (hostiletype == 3
|| (is_demonic[i] && hostiletype == 1)
|| (!is_demonic[i] && hostiletype == 2))
// Mark factions hostile as appropriate.
if (hostiletype == 3
|| (is_demonic[i] && hostiletype == 1)
|| (!is_demonic[i] && hostiletype == 2))
{
mon->attitude = ATT_HOSTILE;
behaviour_event(mon, ME_ALERT, MHITYOU);
}
mon->attitude = ATT_HOSTILE;
behaviour_event(mon, ME_ALERT, MHITYOU);
rc = true;
}
return (rc);
}
// The nicer stuff. Note: these things are not necessarily nice.
static bool _xom_is_good(int sever, int tension)
{
bool done = false;
// Did Xom (already) kill the player?
if (_player_is_dead())
return (true);
god_acting gdact(GOD_XOM);
// This series of random calls produces a poisson-looking
// distribution: initial hump, plus a long-ish tail.
// Don't make the player berserk if there's no danger.
if (tension > 0 && x_chance_in_y(2, sever))
{
done = _xom_do_potion();
}
else if (x_chance_in_y(3, sever))
{
_xom_makes_you_cast_random_spell(sever);
done = true;
}
else if (x_chance_in_y(4, sever))
{
done = _xom_confuse_monsters(sever);
}
// It's pointless to send in help if there's no danger.
else if (tension > 0 && x_chance_in_y(5, sever))
{
done = _xom_send_allies(sever);