git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@8466 c06c8d41-db1a-0410-9941-cceddc491573
PUY2VWZJ3G7HNCLIHZP5VGT2DAGHI436ETDJQTPEBFPRSEHOM2NQC
LPPYA57KUWV53DIXGFMMNJUWBQOH5EDBZFFLYCWXBH347V6OLLCQC
VBZ7XKM6PIJA6CGSHSE7E3Q5GFJ2DUWYGWIOBYJXTPI5NCY7FNAAC
BAQJ26USF7KRR6ALYPXUPUFOYLNGBQVQOS53JXJJWZKDVREHFL2QC
H2OHWQKMHL66CPVJGJL35RY7EIZB74SZTGOLDJDSCG5WVEVPIIUAC
KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC
7RDIBNLUIBTAYOJXJ5Q3DOW3MKKYXBAA3Q4G4QE74KJL23NW6C7AC
A4A2EM75B3AIPYFLGZGTGKJEM72UBMOJK4STS47YARXIJMEC6G7AC
NIJDQAJEWQIYKPDWIXYCCT4JIWVE6CWJ3J3K4N5PPGHWENGNZZXQC
MDSFNRPBJ2SXDV22NZDCO7B3X2H3IOG6WMBTKDKV7BKBGTEIDTSQC
KVTA7IUBD2O7ZEUU5T5VP7D3XVLFLYICXUPP5WCPAODBXKK4DNNQC
BERPOHVI3K3SUE6M4MJVDSJVJ7Q4LWGRZ3SM2AZENUZJLRC2AP3AC
2HG3XZSSPWPPEAPBGO7PBXSJOGJWXIU6UIGEWZZAG54OMM5HQXUQC
22YVHM74WBJNJE4PA5CBEUTDWM6FAGGGILI26A4LXAURX55TNRKAC
KO7PZNWIRLSAPOXUHK7U446ZXT562QCPIT3AYFYKPG7OWRLNBU4QC
PHBACPMH3F34GODHVDKNCMXWU373RJQGVTDLBFCCDLLWDXVYOLTAC
HCVH2CWL32UD66O6Z7ZYDUASWN3RF5TW6FSWURGMD7MELKB772FAC
NYURIMPCM2RADLMIQSN76OPKXQSK4XBLFNXD2OO53KGZI3MA6AQAC
QNQHEILZ3S365ZANMX6PDT3IDMMSXHXRDVWI4HEBA5AMSOIRMQIAC
QEPTJOPJFKTXH27KOHY7DMQSMTXWAM57OPL3Y7WYE4X2OFMZE5IAC
L6ZDC34R3PLXM4UIEOVIAX3X4JIFFTMURK45JECVA5R72H5Q6D4QC
THKQ74QJVQWY4R3OD2XIBEV2RUTGI667KTA2KU6HBGGX5NOIQ3NQC
3XL4DKV7PSWAU3ZBJSKZFJ2VUYABC47I7KKWGIRCJYXULQD453MQC
OTNE6MGPNEJRKXEC36SEFYFZOHD3GPOQZGZC7DBYFG6W5JQ345KQC
4LNIHTHZTCOEZEHZ4GW6WCZH4UCDWKK5UVUKEDODEBBS4YH2KONQC
73URNFZM2NNHOTIYX6RAUXJ27LYPA6K3XA3OOSHGNGAR4KPQJSTAC
K3WXOHMGLLPL4CHGWRK227FWKCMBA7KHLJXLY6DTKEC5LKFJI62QC
KBH6DZPJCNMT3OMEMHKLASTWQZ24FIVNVANBCVI3SEVAMMPSWRWQC
56D656WZS2LWVTXGWPR5FFJ7MDHP25XGPTBMYM4NHT4TKSJILX3QC
AA3I6WU2SPJUPKRIPGXCLU4EZOV4QELVVZ7EIAW3H73GES5DSFXQC
MKI4RE5PG2PMI5XJ4QQNCKMX67E3XL3LTNPRMSCBP4RZFJTBO74QC
4SWAT5KCKQV527NKELAXFQ5XA4Q5HONQXD4VBXMUZNPVPQKPCPNAC
OJKUO2UJ2O2MUITGVQNF3BQITGVYE3XK6QTG7XW6OYPJ4YFWCFQQC
IE3INS4WUXZOBVXB5VWRBYPVPXADD2U2W5H3TBTOYNWJ3EGRSGQQC
GPEJOT73KMACP33IPAKFR5ROGHCOIP22VXZMQNYTGLEA2OSZUM2AC
X4F566X6Y4CWBMYPU547QSHGEOGUH6QDPNRBJVQ4CRJFFICJNCYAC
45CWQUPQHKUFUJ4MVL5K3KCVCCKLY2Z7RZWZ53UT723RV5STPSRAC
TPO6FNMPNUSWH4NCKO3VLYNAADEPSAXLUITCCACLZZSY53PKA62QC
NMZFCCM6O3KO2GJWKOSULN27B3QIZKWPBOB62PAILXMRQD4JMIMAC
ZR4ALQ5F2ETOD3GXMBYXSN6P75DPDGI3C275A7W5XHYI5TGPHNUQC
LQH6T3DTCDOS5LAJ4PIPHMQY6UYRFWMVVUX32YJAELGIVR5RZTGQC
GXXYPBFEWKRZQ6OBGYNS2EXZN52NGNV3UU3WM6S5R74CMJBAKGTAC
WQLOHSNCA3VOMDJF6IINJYKSYVYZEBPJJWBB33QSNE4RP5HEXPMAC
53BVN4ZHKGUAJE53HM6FC6GKUGXOU5QBUT7CLXV2ONS6S5NPW55AC
WEAAN2EBCCSUDTVAREPHLT7L7I7JR64F6MEWODY6QUMV3OAIK4WAC
HZF272SANK2AOSUXM4WVKQKK767KCZUDXOQTHKBAHQPOTDEWEAZQC
V7KMVXS2DILGLKP5XIKXEK7RFEABZGHHCG24QNSMMUAXRJ66THJQC
W3XVTY4C5S3OYK3TY3KDMJP2M7X7RJV33NLGYSEPUPHV2FSVTZCAC
C5YQSTQ76D3OSNKOXBZD5MLX6GISUKXGPXLYZB5VKWZWXRAYPPQAC
GTG5BFLJ5GBLJEEWK6AVZSCL5SQ4VSUW6IWEMZM7PAAT7KTSJQ5QC
25ADVXLZ7BCN6EHSVAZPAX6K75XPJYPG7IVRDY3S5YS5JMQGPMBQC
YCKKYPEEODERLRF5DVJ6IKIXEHLKJQ37COYKGXCEXHMBT5Y2B32QC
NGW2XPEX2XRK3CYC37DNUZSSB5IQLECMKRB6NX257I2X3G35LMPAC
5CPP63H7WJ3GLSHJM4Z2YSU2NISLVESEJ3OYMO4MFZEXVOCV4NIAC
TRBDS4IKHBASW2CTAQ2YHMBMBMRB6QEBQ4ZE7GRSR3U2VJXA7TJQC
5WHLQTLOJRJ67M4KAJZURHMNQLYHBW4XHQFBXV2LUQ4W6YKTOXVAC
O4ZFDG3AEV3K4NPGCCLB7DXUH5CBETKP5FBKLCIET7JNTNDX5DUAC
XDB2YEWS2WYH4FQZG3CIQ7P5JNS47MDYII2MV2IQ6BCAEPBYO5EQC
2RW7ANB4PPWJC2MP2XCBAWBDGMHJUNNWKMXR74JONERE4X522CNQC
5MGUZD2UACJCSG74TEZHI3Z4YL5KL6ZVUCQ3XVZKDOLKM7EMGWJAC
BQ5QKUWLCYSBO4A7EWZN4FXPNSIAR6JPBAZE4PSV6XCUNTV53ERQC
FYSQ7HXDIKXZXDGYVKZMODW7HYQQLRZO52Q2HVM3PYBD37UT5B4AC
K64KYSPAKMNST3HQU25PF5BLVBC2I556MLBWUL7H7GHWKBGAUJIAC
H5TE4QQOGARDI2UGIAQKHBMN7KN7FMBJICHQMEX32NLA4VTHIDDAC
UKBVBVJK23OUOOKQJRGLZWEZYED5KZ4NLODW6U67UEBYCFWGGQOAC
KBIIMBVTWPMMUZLPLK2KJOXKSVMGUREIYJ57VCYVXDX5F23QXDEQC
ERS7DYNAVCC7QUVG5FXJJRONYESLZU22CQGKCA5HLLLG6DMXYRLQC
SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC
UADYVV3UD5ERJTZZJGY4EUQ4NJ2JSBG7YYUJ75ZRBIXRQXQKOJPAC
L7PPUQO4J22WSBEZUEBMKDQADDA4CX5UU3P3PKQABWYXOTQBHNXAC
RDOOG5LBE5TCTFYCKJIB7TGGTRFX4HBLMJZYXS5TCFWNCU3QII5QC
}
rc = true;
}
return (rc);
}
static bool _xom_send_one_ally(int sever)
{
bool rc = false;
const monster_type mon = _xom_random_demon(sever);
const bool is_demonic = (mons_class_holiness(mon) == MH_DEMONIC);
// If we have a non-demon, Xom got it someplace else, so use
// different messages below.
bool different = !is_demonic;
beh_type beha = BEH_FRIENDLY;
unsigned short hitting = you.pet_target;
// There's a chance that a non-demon may be hostile.
if (different && one_chance_in(4))
{
beha = BEH_HOSTILE;
hitting = MHITYOU;
}
const int summons =
create_monster(
mgen_data(mon, beha,
6, MON_SUMM_AID,
you.pos(), hitting,
MG_FORCE_BEH, GOD_XOM));
if (summons != -1)
{
if (different)
god_speaks(GOD_XOM, _get_xom_speech("single holy summon").c_str());
else
god_speaks(GOD_XOM, _get_xom_speech("single summon").c_str());
player_angers_monster(&menv[summons]);
rc = true;
}
return (rc);
}
static bool _xom_good_polymorph_nearby_monster()
{
bool rc = false;
if (there_are_monsters_nearby(false, false))
{
monsters *mon = choose_random_nearby_monster(0,
_choose_mutatable_monster);
if (mon)
{
god_speaks(GOD_XOM,
_get_xom_speech("good monster polymorph").c_str());
bool made_shifter = false;
if (one_chance_in(8) && !mons_is_shapeshifter(mon))
{
mon->add_ench(one_chance_in(3) ? ENCH_GLOWING_SHAPESHIFTER
: ENCH_SHAPESHIFTER);
made_shifter = true;
}
monster_polymorph(mon, RANDOM_MONSTER,
mons_wont_attack(mon) ? PPT_MORE : PPT_LESS,
made_shifter);
rc = true;
}
}
return (rc);
}
// Blink every monster on this level and the player.
static bool _xom_rearrange_pieces(int sever)
{
bool rc = false;
// Every now and then, Xom also confuses them all.
const bool confusem = one_chance_in(10);
// Not just every monster in sight - oh no. Every monster on
// this level!
for (unsigned i = 0; i < MAX_MONSTERS; ++i)
{
monsters* monster = &menv[i];
if (!monster->alive())
continue;
if (monster_blink(monster))
{
// Only give a message once.
if (!rc)
god_speaks(GOD_XOM,
_get_xom_speech("rearrange the pieces").c_str());
if (confusem)
{
if (mons_class_is_confusable(monster->type)
&& monster->add_ench(mon_enchant(ENCH_CONFUSION, 0,
KC_FRIENDLY,
random2(sever))))
{
simple_monster_message(monster, " looks rather confused.");
}
}
rc = true;
// If Xom blinked at least one monster, blink the player,
// too, and then consider this act done.
if (rc)
random_blink(false);
return (rc);
}
static bool _xom_give_good_mutation()
{
bool rc = false;
if (you.can_safely_mutate()
&& player_mutation_level(MUT_MUTATION_RESISTANCE) < 3)
{
god_speaks(GOD_XOM, _get_xom_speech("good mutations").c_str());
mpr("Your body is suffused with distortional energy.");
set_hp(1 + random2(you.hp), false);
deflate_hp(you.hp_max / 2, true);
bool failMsg = true;
for (int i = random2(4); i >= 0; --i)
{
if (mutate(RANDOM_GOOD_MUTATION, failMsg, false, true, false,
false, true))
{
rc = true;
}
else
failMsg = false;
}
}
return (rc);
}
static bool _xom_send_major_ally(int sever)
{
bool rc = false;
const monster_type mon = _xom_random_demon(sever);
const bool is_demonic = (mons_class_holiness(mon) == MH_DEMONIC);
beh_type beha = BEH_FRIENDLY;
unsigned short hitting = you.pet_target;
// There's a chance that a non-demon may be hostile.
if (!is_demonic && one_chance_in(4))
{
beha = BEH_HOSTILE;
hitting = MHITYOU;
}
const int summons =
create_monster(
mgen_data(_xom_random_demon(sever, one_chance_in(8)), beha,
0, 0, you.pos(), hitting,
MG_FORCE_BEH, GOD_XOM));
if (summons != -1)
{
if (is_demonic)
{
god_speaks(GOD_XOM,
_get_xom_speech("single major demon summon").c_str());
}
else
{
god_speaks(GOD_XOM,
_get_xom_speech("single major holy summon").c_str());
}
player_angers_monster(&menv[summons]);
static bool _xom_throw_divine_lightning()
{
if (!player_in_a_dangerous_place())
return (false);
if (you.hp <= random2(201))
you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1;
god_speaks(GOD_XOM, "The area is suffused with divine lightning!");
bolt beam;
beam.beam_source = NON_MONSTER;
beam.type = dchar_glyph(DCHAR_FIRED_BURST);
beam.damage = dice_def(3, 30);
beam.flavour = BEAM_ELECTRICITY;
beam.target = you.pos();
beam.name = "blast of lightning";
beam.colour = LIGHTCYAN;
beam.thrower = KILL_MISC;
beam.aux_source = "Xom's lightning strike";
beam.ex_size = 2;
beam.is_tracer = false;
beam.is_explosion = true;
beam.explode();
if (you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION])
{
mpr("Your divine protection wanes.");
you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0;
}
{
monster_type mon = _xom_random_demon(sever);
const bool is_demonic = (mons_class_holiness(mon) == MH_DEMONIC);
// If we have a non-demon, Xom got it someplace else, so use
// different messages below.
bool different = !is_demonic;
beh_type beha = BEH_FRIENDLY;
unsigned short hitting = you.pet_target;
// There's a chance that a non-demon may be hostile.
if (different && one_chance_in(4))
{
beha = BEH_HOSTILE;
hitting = MHITYOU;
}
const int summons =
create_monster(
mgen_data(mon, beha,
6, MON_SUMM_AID,
you.pos(), hitting,
MG_FORCE_BEH, GOD_XOM));
if (summons != -1)
{
if (different)
god_speaks(GOD_XOM, _get_xom_speech("single holy summon").c_str());
else
god_speaks(GOD_XOM, _get_xom_speech("single summon").c_str());
player_angers_monster(&menv[summons]);
done = true;
}
}
done = _xom_send_one_ally(sever);
{
if (there_are_monsters_nearby(false, false))
{
monsters *mon =
choose_random_nearby_monster(0, _choose_mutatable_monster);
if (mon)
{
god_speaks(GOD_XOM,
_get_xom_speech("good monster polymorph").c_str());
bool made_shifter = false;
if (one_chance_in(8) && !mons_is_shapeshifter(mon))
{
mon->add_ench(one_chance_in(3) ?
ENCH_GLOWING_SHAPESHIFTER : ENCH_SHAPESHIFTER);
made_shifter = true;
}
monster_polymorph(mon, RANDOM_MONSTER,
mons_wont_attack(mon) ? PPT_MORE : PPT_LESS, made_shifter);
done = true;
}
}
}
done = _xom_good_polymorph_nearby_monster();
{
// Rearrange the pieces - blink every monster on this level and
// the player.
// Every now and then, Xom also confuses them all.
const bool confusem = one_chance_in(10);
// Not just every monster in sight - oh no. Every monster on
// this level!
for (unsigned i = 0; i < MAX_MONSTERS; ++i)
{
monsters* monster = &menv[i];
if (!monster->alive())
continue;
if (monster_blink(monster))
{
if (!done)
god_speaks(GOD_XOM, _get_xom_speech("rearrange the pieces").c_str());
if (confusem)
{
if (mons_class_is_confusable(monster->type)
&& monster->add_ench(mon_enchant(ENCH_CONFUSION, 0,
KC_FRIENDLY, random2(sever))))
{
simple_monster_message(monster,
" looks rather confused.");
}
}
done = true;
}
// If he blinked at least one monster, blink the player,
// too, and then consider this act done.
if (done)
random_blink(false);
}
}
done = _xom_rearrange_pieces(sever);
if (you.can_safely_mutate()
&& player_mutation_level(MUT_MUTATION_RESISTANCE) < 3)
{
god_speaks(GOD_XOM, _get_xom_speech("good mutations").c_str());
mpr("Your body is suffused with distortional energy.");
set_hp(1 + random2(you.hp), false);
deflate_hp(you.hp_max / 2, true);
bool failMsg = true;
for (int i = random2(4); i >= 0; --i)
{
if (mutate(RANDOM_GOOD_MUTATION, failMsg, false, true, false,
false, true))
{
done = true;
}
else
failMsg = false;
}
}
done = _xom_give_good_mutation();
{
monster_type mon = _xom_random_demon(sever);
const bool is_demonic = (mons_class_holiness(mon) == MH_DEMONIC);
// If we have a non-demon, Xom got it someplace else, so use
// different messages below.
bool different = !is_demonic;
beh_type beha = BEH_FRIENDLY;
unsigned short hitting = you.pet_target;
// There's a chance that a non-demon may be hostile.
if (different && one_chance_in(4))
{
beha = BEH_HOSTILE;
hitting = MHITYOU;
}
const int summons =
create_monster(
mgen_data(_xom_random_demon(sever, one_chance_in(8)), beha,
0, 0, you.pos(), hitting,
MG_FORCE_BEH, GOD_XOM));
if (summons != -1)
{
if (different)
god_speaks(GOD_XOM, _get_xom_speech("single major holy summon").c_str());
else
god_speaks(GOD_XOM, _get_xom_speech("single major demon summon").c_str());
player_angers_monster(&menv[summons]);
done = true;
}
}
done = _xom_send_major_ally(sever);
{
if (player_in_a_dangerous_place())
{
if (you.hp <= random2(201))
you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1;
god_speaks(GOD_XOM, "The area is suffused with divine lightning!");
bolt beam;
beam.beam_source = NON_MONSTER;
beam.type = dchar_glyph(DCHAR_FIRED_BURST);
beam.damage = dice_def(3, 30);
beam.flavour = BEAM_ELECTRICITY;
beam.target = you.pos();
beam.name = "blast of lightning";
beam.colour = LIGHTCYAN;
beam.thrower = KILL_MISC;
beam.aux_source = "Xom's lightning strike";
beam.ex_size = 2;
beam.is_tracer = false;
beam.is_explosion = true;
beam.explode();
if (you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION])
{
mpr("Your divine protection wanes.");
you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0;
}
// Don't accidentally kill the player when doing a good act.
if (you.escaped_death_cause == KILLED_BY_WILD_MAGIC
&& you.escaped_death_aux == "Xom's lightning strike")
{
you.hp = 1;
you.reset_escaped_death();
}
done = _xom_throw_divine_lightning();