git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@1489 c06c8d41-db1a-0410-9941-cceddc491573
KFULGQQOHWUTXOM3BXCCYPGGVGGY4Z6265XUFRCBPNLTZAEHJZSQC ONKB2ZZ2MWY7UGPBHW6EE4N3EEPJONPRRALEFZZR2YTZHNEIGV5AC GRH4XPIYHDOXXF3R3QPMZTFHGLO2OJAZS4FLNBBXG3DHTQQM7RDQC SW3RLYFNRT3IJBK6LYKHKP2J2YDU7SXQWAJZX7U6S7ICYW43OMNQC JVSCP4FTW2G57C6YD5HZOZXTODGZH7TR75JQGFJBEPX3LCZH236QC X2FMEN4E345XD26Z2X7JMJ7VGHOGCGIELMHQRE2ITLVNQACP3NOQC QKGDOYIYKE6B36ION5O2DRW65DWWPZMYNWJVH7LJJ7FPGGM2MYAQC APMT6XTVAD4ZCXCMUPTW5KCNR7TXW6W37SNYUP5A6NLFLXT3BCYQC UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC JW2KRJHES33W7UTWZ6NDO4TLMK4EFU4HKZXBWR2UJOMPCCOTR4CQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC CJ6OSJQPAZOGWC56OYBALICSITGVUEQERE7LWIYJL2AXWRZE523AC Y7ZDLE2BHSLBQUXBWLAFBJXXIH5WYGPBRJDIH33WX7VPLO7PFODQC 2Q3P7FHAAZRJ337GTR2ZLD72ECBUDJ42MROKVCNKNDV6CGMQOSYAC 3NFVCXRVGHN2CHLLWFZES5RBS4R2BCDS4EEQNSDCFYIFQWQK7MUQC X5WLJCJVW55SXZVP7IKP7ADCJIGNKN4PKAXFECVR6TNK7XSMZR7QC TV3ZC6WOZKSQQJQN26JIVKCHK6UK7WMDBYZDUYRWEAZ4JB4YVNAAC 74LQ7JXVLAFSHLI7LCBKFX47CNTYSKGUQSXNX5FCIUIGCC2JTR3QC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC L4PKJZERR7WADKWHY3MR6J6OZFREVPL3CB43I6MLJ2BVKWCUTE7AC 6L4EP4ZRWWYLT55PD5KTTJON5J2JB5VV5MWNHF5VPZQZ5BKEYZ4QC 77H4BWWPPGLM3PLZH4QTAJRXIZTSDVNCOKZE223I437FN2UJ34RQC 3GSAVTNKEG45AT2U734R5STSRP22WJZL3H6KUFRUWCIA6A4CZE5QC QDTVLBRGHDTRUVT7I3O72K6TMOYAUSAJBZUHGOEFU2RKJNUPWZSQC HH3HFWVXABJ4IRMN22PPJCREMULZSN6DA7VYKOGECGMNUQTZ5QNQC 43ZTEB57FU7KE5EVMYWZONNVJBZCGF3JEAJZIY25LC4LGE65PG5QC EIULXYQC3OPXDGTBRDOI7ITILQ22RGEGG6UFCGY2O5HD7SN5NUUQC MOT3YZFRY3JG2MH3GN2VD6IY3IJSAXJUXMXS222TXWKRFCENOCDQC VIFRP3HZEONFR6PQRYZYM3YUEJOQ7T4F5CZY4MN4YJMB23FMU7XAC 7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC ACKNLTFL2RI3PMRWLNRVLRWGQAMLRFKNGNS5LED6NFE5GVGFIHFAC R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC BIZDHHK5LIO57S5AKHEPJFLWV5DAFKZIKYBGOUNGICSWTX7DCXKAC UDYVF65OZSNPANLHDI3ODBEGUAKAVZ4KH4OZFAKR2CQJPO4AXU6QC R325RPUV26YH65VIJKYEFZ2XCVXQHO5N3ELPX6RNQ5TSI3JJNQGQC 5UVDIVD4NSXA52U4QMQIVST3GSZJ2A2YZK3RUEXKPM43YVQ7LI5AC ZP2KE7A2LE7Z2S7AC45WE4CXDSEVDTWIMV2EM4IBUKXYJIDU6R7QC JDM27QE4HR52AYFSQE763BFF57ANOTF5MXKMO377PP5EXMN7SAOAC DTO3EUKWHZ5RJNGNCFYXSOVTIPVXPP637F2W7WFGYKJ7JK7VNKNQC MQ62OAMLGJVRW2QIL4PAZRAU6PC52ZVGY2FCOBIY6IWGQIHMU5CAC GCIZIUXO5TYROKDUYB3HAY7H7MRDTJNM7HR7DGSH7KXDIZC2LCDAC TOKBONNNPTP2CIEHMMR4QAJZTXYETS55OGGDA6FY6NIMNDYMWJDAC QVVC7AYGVA6U64PTNA7L27422NLMO327P22BQKXEVIMPZHIHO7MQC B62ICMDTN5V7R7RBL4JALFVKEMVOOVLRSJASRNYS6CGFWBEEF5JQC TAVHZJPVNJBZR7CUURAOYNDZPNVQ3AGHTXDEP5K4JGYETBLQJDRQC RISMOCQM6BKK4XSIRKYLOBB2UPDYJNDAL6OGIIR5GGNZQAK5YSZAC W5VEC2PBIM5DMU5233HOWAZUEPTGWJRZZIA3H35YYQQW6BTP6XUAC ITDUEUO7XAZANPC4GRB3SEDFBOV7GLFPNPTYE5LYNC3CS6BSVZTQC T7PHMSG47WP4MTKIGVBP4EAQRGXHMZPYSI3GT3DAEWKHUDFCH3QQC /** File: xom.cc* Summary: All things Xomly* Written by: Zooko** Modified for Crawl Reference by $Author: haranp $ on $Date: 2007-05-15T17:02:30.826843Z $*/#include "AppHdr.h"#include "beam.h"#include "effects.h"#include "it_use2.h"#include "items.h"#include "makeitem.h"#include "misc.h"#include "mon-util.h"#include "monplace.h"#include "monstuff.h"#include "mutation.h"#include "ouch.h"#include "player.h"#include "religion.h"#include "spells3.h"#include "spl-cast.h"#include "stuff.h"#include "view.h"// Which spell? First I copied all spells from you_spells(), then I// filtered some out (especially conjurations). Then I sorted them in// roughly ascending order of power. ([ds] Removed SUMMON_GUARDIAN and// SUMMON_DAEVA which are inappropriate for a god of chaos; need to// investigate substitutes).//static const spell_type xom_spells[] ={SPELL_BLINK, SPELL_CONFUSING_TOUCH, SPELL_MAGIC_MAPPING,SPELL_DETECT_ITEMS, SPELL_DETECT_CREATURES, SPELL_MASS_CONFUSION,SPELL_MASS_SLEEP, SPELL_CONTROLLED_BLINK, SPELL_STONESKIN,SPELL_RING_OF_FLAMES, SPELL_OLGREBS_TOXIC_RADIANCE,SPELL_TUKIMAS_VORPAL_BLADE, SPELL_FIRE_BRAND, SPELL_FREEZING_AURA,SPELL_POISON_WEAPON, SPELL_STONEMAIL, SPELL_WARP_BRAND, SPELL_ALTER_SELF,SPELL_TUKIMAS_DANCE, SPELL_SUMMON_BUTTERFLIES, SPELL_SUMMON_SMALL_MAMMAL,SPELL_CALL_IMP, SPELL_SUMMON_SCORPIONS, SPELL_FLY, SPELL_SPIDER_FORM,SPELL_STATUE_FORM, SPELL_ICE_FORM, SPELL_DRAGON_FORM, SPELL_SWARM,SPELL_SUMMON_WRAITHS, SPELL_SHADOW_CREATURES, SPELL_SUMMON_ELEMENTAL,SPELL_SUMMON_HORRIBLE_THINGS, SPELL_SUMMON_LARGE_MAMMAL,SPELL_CONJURE_BALL_LIGHTNING, SPELL_SUMMON_DRAGON, SPELL_DEATH_CHANNEL,SPELL_NECROMUTATION};static const char *xom_try_this[] ={"\"Perhaps you should try this instead.\"","\"Maybe this would work better.\"","\"Catch!\""};static const char *xom_try_this_ring[] ={"\"Try this.\"","\"Catch!\"","\"Take this!\""};static const char *xom_try_this_other_thing[] ={"\"Perhaps you should try this instead.\"","\"Have you considered using one of these?\"","\"How about this?\""};static const char *xom_try_these_duds[] ={"\"Perhaps you should try this instead.\"","\"Have you considered wearing one of these?\"","\"Here you go.\""};static const char *xom_generic_beneficence[] ={"Xom grants you a gift!","\"Here.\"","Xom's generous nature manifests itself.","Xom grants you an implement of some kind.","\"Take this instrument of something!\"","\"Take this token of my esteem.\"","Xom smiles on you."};const char *describe_xom_favour(){return (you.piety > 160) ? "A beloved toy of Xom." :(you.piety > 145) ? "A favorite toy of Xom." :(you.piety > 130) ? "A very special toy of Xom." :(you.piety > 115) ? "A special toy of Xom." :(you.piety > 100) ? "A toy of Xom." :(you.piety > 85) ? "A plaything of Xom." :(you.piety > 70) ? "A special plaything of Xom." :(you.piety > 55) ? "A very special plaything of Xom." :(you.piety > 40) ? "A favorite plaything of Xom." :"A beloved plaything of Xom.";}bool xom_is_nice(){return (you.gift_timeout > 0 && you.piety > 100);}void xom_is_stimulated(int maxinterestingness){if (you.religion != GOD_XOM)return;int interestingness = random2(maxinterestingness);if (interestingness < 12)return;if (interestingness > 255)interestingness = 255;if (interestingness > you.gift_timeout){you.gift_timeout = interestingness;god_speaks(GOD_XOM,((interestingness > 200) ? "Xom roars with laughter!" :(interestingness > 100) ? "Xom thinks this is hilarious!" :(interestingness > 75) ? "Xom is highly amused!" :(interestingness > 50) ? "Xom is amused." :(interestingness > 25) ? "Xom is mildly amused." :"Xom is interested."));}if (you.piety < 100 && coinflip())you.piety = 200 - you.piety;}void xom_makes_you_cast_random_spell(int sever){int spellenum = sever;const int nxomspells = ARRAYSIZE(xom_spells);if (spellenum >= nxomspells)spellenum = nxomspells - 1;const spell_type spell = xom_spells[random2(spellenum)];god_speaks(GOD_XOM, "Xom's power flows through you!");#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS,"Xom_acts();spell: %d, spellenum: %d", spell, spellenum);#endifyour_spells(spell, sever, false);}static void xom_make_item(object_class_type base,int subtype,int power,const char *failmsg = "\"No, never mind.\""){int thing_created =items(true, base, subtype, true, power, MAKE_ITEM_RANDOM_RACE);if (thing_created == NON_ITEM){god_speaks(GOD_XOM, failmsg);return;}move_item_to_grid( &thing_created, you.x_pos, you.y_pos );canned_msg(MSG_SOMETHING_APPEARS);origin_acquired(mitm[thing_created], GOD_XOM);}static void xom_suggest(const char **messages, int nmsgs){if (nmsgs && messages){const char *sel = messages[random2(nmsgs)];if (sel)god_speaks(GOD_XOM, sel);}}#define XOM_SAY(x) xom_suggest(x, ARRAYSIZE(x))static object_class_type get_unrelated_wield_class(object_class_type ref){object_class_type objtype = OBJ_WEAPONS;if (ref == OBJ_WEAPONS){if (random2(10))objtype = OBJ_STAVES;elseobjtype = OBJ_MISCELLANY;}else if (ref == OBJ_STAVES){if (random2(10))objtype = OBJ_WEAPONS;elseobjtype = OBJ_MISCELLANY;}else{const int temp_rand = random2(3);objtype =(temp_rand == 0) ? OBJ_WEAPONS :(temp_rand == 1) ? OBJ_STAVES :OBJ_MISCELLANY;}return (objtype);}static bool xom_annoyance_gift(int power){if (coinflip() && player_in_a_dangerous_place()){const item_def *weapon = you.weapon();// Xom has a sense of humour.if (coinflip() && weapon && weapon->cursed()){// If you are wielding a cursed item on then Xom will give// you an item of that same type. Ha ha!XOM_SAY(xom_try_this);if (coinflip())// For added humour, give the same sub-type.xom_make_item(weapon->base_type, weapon->sub_type, power * 3);elseacquirement(weapon->base_type, GOD_XOM);return (true);}const item_def *gloves = you.slot_item(EQ_GLOVES);if (coinflip() && gloves && gloves->cursed()){// If you are wearing cursed gloves then Xom will give you// a ring. Ha ha!//// A random ring. (Not necessarily a good one.)XOM_SAY(xom_try_this);xom_make_item(OBJ_JEWELLERY, get_random_ring_type(), power * 3);return (true);};const item_def *amulet = you.slot_item(EQ_AMULET);if (coinflip() && amulet && amulet->cursed()){// If you are wearing a cursed amulet then Xom will give// you an amulet. Ha ha!XOM_SAY(xom_try_this);xom_make_item(OBJ_JEWELLERY, get_random_amulet_type(), power * 3);return (true);};const item_def *left_ring = you.slot_item(EQ_LEFT_RING);const item_def *right_ring = you.slot_item(EQ_RIGHT_RING);if (coinflip() && ((left_ring && left_ring->cursed())|| (right_ring && right_ring->cursed()))){// If you are wearing a cursed ring then Xom will give you// a ring. Ha ha!XOM_SAY(xom_try_this_ring);xom_make_item(OBJ_JEWELLERY, get_random_ring_type(), power * 3);return (true);}if (one_chance_in(5) && weapon){// Xom will give you a wielded item of a type different// than what you are currently wielding.XOM_SAY(xom_try_this_other_thing);const object_class_type objtype =get_unrelated_wield_class(weapon->base_type);if (power > random2(256))acquirement(objtype, GOD_XOM);elsexom_make_item(objtype, OBJ_RANDOM, power * 3);return (true);}}return (false);}bool xom_gives_item(int power){if (xom_annoyance_gift(power))return (true);const item_def *cloak = you.slot_item(EQ_CLOAK);if (coinflip() && cloak && cloak->cursed()){// If you are wearing a cursed cloak then Xom will give you a// cloak or body armour . Ha ha!XOM_SAY(xom_try_these_duds);xom_make_item(OBJ_ARMOUR,random2(10)?get_random_body_armour_type(you.your_level * 2): ARM_CLOAK,power * 3);return (true);}XOM_SAY(xom_generic_beneficence);// There are two kinds of Xom gifts: acquirement and random// object. The result from acquirement is very good (usually as// good or better than random object), and it is sometimes tuned// to the player's skills and nature. Being tuned to the player's// skills and nature is not very Xomlike...if (power > random2(256)){// random-type acquirementconst int r = random2(7);const object_class_type objtype = (r == 0) ? OBJ_WEAPONS :(r == 1) ? OBJ_ARMOUR :(r == 2) ? OBJ_JEWELLERY :(r == 3) ? OBJ_BOOKS :(r == 4) ? OBJ_STAVES :(r == 5) ? OBJ_FOOD :(r == 6) ? OBJ_MISCELLANY :OBJ_GOLD;acquirement(objtype, GOD_XOM);}else{// random-type random objectxom_make_item(OBJ_RANDOM, OBJ_RANDOM, power * 3);}more();return (true);}bool there_are_monsters_nearby(){int ystart = you.y_pos - 9, xstart = you.x_pos - 9;int yend = you.y_pos + 9, xend = you.x_pos + 9;if (xstart < 0) xstart = 0;if (ystart < 0) ystart = 0;if (xend >= GXM) xend = GXM;if (ystart >= GYM) yend = GYM;/* monster check */for ( int y = ystart; y < yend; ++y ){for ( int x = xstart; x < xend; ++x ){/* if you can see a nonfriendly monster then you feelunsafe */if ( see_grid(x,y) ){const int targ_monst = mgrd[x][y];if ( targ_monst != NON_MONSTER ){const monsters *mon = &menv[targ_monst];if (!mons_is_submerged(mon))return (true);}}}}return (false);}monsters *get_random_nearby_monster(){monsters *monster = NULL;/* not particular efficient, but oh well */for (int it = 0, num = 0; it < MAX_MONSTERS; it++){monsters *mons = &menv[it];if (mons->alive() && mons_near(mons)&& !mons_is_submerged(mons)&& one_chance_in(++num)){monster = mons;}}return (monster);}static bool xom_is_good(int sever){// niceness = false - bad, true - niceint temp_rand; // probability determination {dlb}bool done = false;bolt beam;// Okay, now for the nicer stuff (note: these things are not// necessarily nice):if (random2(sever) <= 1){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Go forth and destroy!\"" :(temp_rand == 1) ? "\"Go forth and cause havoc, mortal!\"" :(temp_rand == 2) ? "Xom grants you a minor favour.": "Xom smiles on you.");switch (random2(7)){case 0:potion_effect(POT_HEALING, 150);break;case 1:potion_effect(POT_HEAL_WOUNDS, 150);break;case 2:potion_effect(POT_SPEED, 150);break;case 3:potion_effect(POT_MIGHT, 150);break;case 4:potion_effect(POT_INVISIBILITY, 150);break;case 5:if (one_chance_in(6))potion_effect(POT_EXPERIENCE, 150);else{you.berserk_penalty = NO_BERSERK_PENALTY;potion_effect(POT_BERSERK_RAGE, 150);}break;case 6:you.berserk_penalty = NO_BERSERK_PENALTY;potion_effect(POT_BERSERK_RAGE, 150);break;}done = true;}else if (random2(sever) <= 2){xom_makes_you_cast_random_spell(sever);done = true;}else if (random2(sever) <= 3){temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Serve the mortal, my children!\"" :(temp_rand == 1) ? "Xom grants you some temporary aid.": "Xom momentarily opens a gate.");int i;int r = random2(random2(random2(sever+1)+1)+1)+2;int numdemons = MIN(r, 24);for (i=0; i < numdemons; i++){r = random2(random2(random2(sever)));int demonnum = MONS_WHITE_IMP + MIN(r, 20);if (!player_res_poison()){while (demonnum == MONS_GREEN_DEATH){r = random2(random2(random2(sever)));demonnum = MONS_WHITE_IMP + MIN(r, 20);}}ASSERT (demonnum >= MONS_WHITE_IMP);ASSERT (demonnum <= MONS_WHITE_IMP+20);create_monster(demonnum, 3,BEH_GOD_GIFT, you.x_pos, you.y_pos,you.pet_target, 250 );}done = true;}else if (random2(sever) <= 4){xom_gives_item(sever);done = true;}else if (random2(sever) <= 5){int r = random2(random2(random2(sever)));int demonnum = MONS_WHITE_IMP + MIN(r, 20);ASSERT (demonnum >= MONS_WHITE_IMP);ASSERT (demonnum <= MONS_WHITE_IMP+20);if (!player_res_poison()){while (demonnum == MONS_GREEN_DEATH){r = random2(random2(random2(sever)));demonnum = MONS_WHITE_IMP + MIN(r, 20);}}if (create_monster( demonnum, 6,BEH_GOD_GIFT, you.x_pos, you.y_pos,you.pet_target, 250 ) != -1){temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Serve the mortal, my child!\"" :(temp_rand == 1) ? "Xom grants you a demonic assistant.": "Xom opens a gate so that something can appear.");done = true;}}else if ((random2(sever) <= 6) && there_are_monsters_nearby()){if (monsters* mon = get_random_nearby_monster()){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"This might be better!\"" :(temp_rand == 1) ? "\"Hum-dee-hum-dee-hum...\"" :(temp_rand == 2) ?"Xom's power touches on a nearby monster.": "You hear Xom's avuncular chuckle.");bool isFriendly = mons_friendly(mon);if (isFriendly)monster_polymorph(mon, RANDOM_MONSTER, PPT_MORE);elsemonster_polymorph(mon, RANDOM_MONSTER, PPT_LESS);done = true;}}else if (random2(sever) <= 7){xom_gives_item(sever);done = true;}else if (!you.is_undead && random2(sever) <= 8){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You need some minor adjustments, mortal!\"" :(temp_rand == 1) ? "\"Let me alter your pitiful body.\"" :(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal chuckling.");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;int i = 0;int j = random2(4);while (i < j){if (mutate(100, failMsg, true))done = true;elsefailMsg = false;i++;}}else if (random2(sever) <= 9){int r = random2(random2(random2(sever)));int demonnum = MONS_WHITE_IMP + MIN(r, 20);if (!player_res_poison()){while (demonnum == MONS_GREEN_DEATH){r = random2(random2(random2(sever)));demonnum = MONS_WHITE_IMP + MIN(r, 20);}}if (create_monster( demonnum, 0, BEH_GOD_GIFT,you.x_pos, you.y_pos, you.pet_target, 250 ) != -1){temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Serve the toy, my child!\"" :(temp_rand == 1) ? "Xom grants you a demonic servitor.": "Xom opens a gate.");done = true;}}else if ((random2(sever) <= 10) && player_in_a_dangerous_place()){bool lightningprot = false;if (you.hp <= random2(201)&& !you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION]){you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1;lightningprot = true;} elselightningprot = false;mpr("The area is suffused with divine lightning!");beam.beam_source = NON_MONSTER;beam.type = SYM_BURST;beam.damage = dice_def( 3, 30 );beam.flavour = BEAM_ELECTRICITY;beam.target_x = you.x_pos;beam.target_y = you.y_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;explosion(beam);if (lightningprot){mpr("Your divine protection wanes.");you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0;}done = true;}return (done);}static bool xom_is_bad(int sever){// niceness = false - bad, true - niceint temp_rand; // probability determination {dlb}bool done = false;bolt beam;// begin "Bad Things"while (!done){if (random2(sever) <= 2){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "Xom almost notices you." :(temp_rand == 1) ? "Xom's attention almost turns to you for a moment.":(temp_rand == 2) ? "Xom's power almost touches on you for a moment.": "You almost hear Xom's maniacal laughter.");miscast_effect( SPTYP_RANDOM, 0, 0, 0,"the mischievity of Xom" );done = true;}else if (random2(sever) <= 3){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "Xom notices you." :(temp_rand == 1) ? "Xom's attention turns to you for a moment.":(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");miscast_effect( SPTYP_RANDOM, 0, 0, random2(2),"the capriciousness of Xom" );done = true;}else if (random2(sever) <= 4){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Suffer!\"" :(temp_rand == 1) ? "Xom's malign attention turns to you for a moment." :(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");lose_stat(STAT_RANDOM, 1 + random2(3), true);done = true;}else if (random2(sever) <= 5){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "Xom notices you." :(temp_rand == 1) ? "Xom's attention turns to you for a moment.":(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");miscast_effect( SPTYP_RANDOM, 0, 0, random2(3),"the capriciousness of Xom" );done = true;}else if (!you.is_undead && random2(sever) <= 6){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You need some minor improvements, mortal!\"" :(temp_rand == 1) ? "\"Let me alter your body.\"" :(temp_rand == 2) ? "Xom's power brushes against you for a moment.": "You hear Xom's avuncular chuckle.");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 = 0; i < random2(4)+1; i++){if (mutate(101, failMsg, true))done = true;elsefailMsg = false;}}else if ((random2(sever) <= 7) && there_are_monsters_nearby()){struct monsters* mon = get_random_nearby_monster();ASSERT (mon != NULL);temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"This might be better!\"" :(temp_rand == 1) ? "\"Hum-dee-hum-dee-hum...\"" :(temp_rand == 2) ? "Xom's power touches on a nearby monster.": "You hear Xom's avuncular chuckle.");bool isFriendly = mons_friendly(mon);if (isFriendly)monster_polymorph(mon, RANDOM_MONSTER, PPT_LESS);elsemonster_polymorph(mon, RANDOM_MONSTER, PPT_MORE);done = true;}else if (!you.is_undead && random2(sever) <= 8){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You have displeased me, mortal.\"" :(temp_rand == 1) ? "\"You have grown too confident for your meagre worth.\"" :(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");if (one_chance_in(4)){drain_exp();if (random2(sever) > 3)drain_exp();if (random2(sever) > 3)drain_exp();}else{mpr("A wave of agony tears through your body!");set_hp(1 + (you.hp / 2), false);}done = true;}else if (random2(sever) <= 9){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Time to have some fun!\"" :(temp_rand == 1) ? "\"Fight to survive, mortal.\"" :(temp_rand == 2) ? "\"Let's see if it's strong enough to survive yet.\"": "You hear Xom's maniacal laughter.");if (one_chance_in(4))dancing_weapon(100, true); // nasty, but funelse{int r = random2(random2(random2(sever+1)+1)+1)+1;int numdemons = MIN(r, 24);for (int i = 0; i < numdemons; i++){create_monster(MONS_WHITE_IMP +random2(random2(random2(MIN(sever, 22)))),4,BEH_HOSTILE, you.x_pos, you.y_pos,MHITNOT, 250);}}done = true;}else if (random2(sever) <= 10){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Try this!\"" :(temp_rand == 1) ? "Xom's attention turns to you.":(temp_rand == 2) ? "Xom's power touches on you.": "Xom giggles.");miscast_effect( SPTYP_RANDOM, 0, 0, random2(4),"the severe capriciousness of Xom" );done = true;}else if ((random2(sever) == 0) && (you.level_type != LEVEL_ABYSS)){temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You have grown too comfortable in your little world, mortal!\"" :(temp_rand == 1) ? "Xom casts you into the Abyss!": "The world seems to spin as Xom's maniacal laughter rings in your ears.");banished(DNGN_ENTER_ABYSS);done = true;}}return (done);}void xom_acts(bool niceness, int sever){#if DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Xom_acts(%u, %d); piety: %u, interest: %u\n",niceness, sever, you.piety, you.gift_timeout);#endifif (sever < 1)sever = 1;if (niceness){// Good stuff.while (!xom_is_good(sever));}else{// Bad mojo.while (!xom_is_bad(sever));}if (coinflip())you.piety = 200 - you.piety;}
} // end you_teleport()
return !is_controlled;}void you_teleport_now( bool allow_control, bool new_abyss_area ){const bool randtele = teleport_player(allow_control, new_abyss_area);// Xom is amused by uncontrolled teleports that land you in a// dangerous place.if (randtele && player_in_a_dangerous_place())xom_is_stimulated(255);}
void gain_piety(char pgn);void god_speaks( int god, const char *mesg );void lose_piety(char pgn);
void gain_piety(int pgn);void god_speaks(god_type god, const char *mesg );void lose_piety(int pgn);
if (one_chance_in(100)){// Every now and then, Xom listens// This is for flavour, not effect, so praying should not be// encouraged.// Xom is nicer to experienced playersbool nice = (27 <= random2( 27 + you.experience_level ));
mpr("Xom ignores you.");
void Xom_acts(bool niceness, int sever, bool force_sever){// niceness = false - bad, true - niceint temp_rand; // probability determination {dlb}bool done_bad = false; // flag to clarify logic {dlb}bool done_good = false; // flag to clarify logic {dlb}struct bolt beam;if (sever < 1)sever = 1;if (!force_sever)sever = random2(sever);if (sever == 0)return;okay_try_again:if (!niceness || one_chance_in(3)){// begin "Bad Things"done_bad = false;// this should always be first - it will often be called// deliberately, with a low sever valueif (random2(sever) <= 2){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "Xom notices you." :(temp_rand == 1) ? "Xom's attention turns to you for a moment.":(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");miscast_effect( SPTYP_RANDOM, 5 + random2(10), random2(100), 0,"the capriciousness of Xom" );done_bad = true;}else if (random2(sever) <= 2){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Suffer!\"" :(temp_rand == 1) ? "Xom's malign attention turns to you for a moment." :(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");lose_stat(STAT_RANDOM, 1 + random2(3), true);done_bad = true;}else if (random2(sever) <= 2){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "Xom notices you." :(temp_rand == 1) ? "Xom's attention turns to you for a moment.":(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");miscast_effect( SPTYP_RANDOM, 5 + random2(15), random2(250), 0,"the capriciousness of Xom" );done_bad = true;}else if (!you.is_undead && random2(sever) <= 3){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You need some minor adjustments, mortal!\"" :(temp_rand == 1) ? "\"Let me alter your pitiful body.\"" :(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");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 = 0; i < 4; i++){if (!mutate(100, failMsg))failMsg = false;}done_bad = true;}else if (!you.is_undead && random2(sever) <= 3){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You have displeased me, mortal.\"" :(temp_rand == 1) ? "\"You have grown too confident for your meagre worth.\"" :(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal laughter.");if (one_chance_in(4)){drain_exp();if (random2(sever) > 3)drain_exp();if (random2(sever) > 3)drain_exp();}else{mpr("A wave of agony tears through your body!");set_hp(1 + (you.hp / 2), false);}done_bad = true;}else if (random2(sever) <= 3){temp_rand = random2(4);
god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Time to have some fun!\"" :(temp_rand == 1) ? "\"Fight to survive, mortal.\"" :(temp_rand == 2) ? "\"Let's see if it's strong enough to survive yet.\"": "You hear Xom's maniacal laughter.");if (one_chance_in(4) && (you.equip[EQ_WEAPON] != -1) )dancing_weapon(100, true); // nasty, but funelse{create_monster(MONS_NEQOXEC + random2(5), 3,BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);if (one_chance_in(3))create_monster(MONS_NEQOXEC + random2(5), 3,BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);if (one_chance_in(4))create_monster(MONS_NEQOXEC + random2(5), 3,BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);if (one_chance_in(3))create_monster(MONS_HELLION + random2(10), 3,BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);if (one_chance_in(4))create_monster(MONS_HELLION + random2(10), 3,BEH_HOSTILE, you.x_pos, you.y_pos, MHITNOT, 250);}done_bad = true;}else if (you.your_level == 0){// this should remain the last possible outcome {dlb}temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You have grown too comfortable in your little world, mortal!\"" :(temp_rand == 1) ? "Xom casts you into the Abyss!": "The world seems to spin as Xom's maniacal laughter rings in your ears.");banished(DNGN_ENTER_ABYSS, "Xom");done_bad = true;}} // end "Bad Things"else{// begin "Good Things"done_good = false;// Okay, now for the nicer stuff (note: these things are not necessarily nice):if (random2(sever) <= 2){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Go forth and destroy!\"" :(temp_rand == 1) ? "\"Go forth and destroy, mortal!\"" :(temp_rand == 2) ? "Xom grants you a minor favour.": "Xom smiles on you.");switch (random2(7)){case 0:potion_effect(POT_HEALING, 150);break;case 1:potion_effect(POT_HEAL_WOUNDS, 150);break;case 2:potion_effect(POT_SPEED, 150);break;case 3:potion_effect(POT_MIGHT, 150);break;case 4:potion_effect(POT_INVISIBILITY, 150);break;case 5:if (one_chance_in(6))potion_effect(POT_EXPERIENCE, 150);else{you.berserk_penalty = NO_BERSERK_PENALTY;potion_effect(POT_BERSERK_RAGE, 150);}break;case 6:you.berserk_penalty = NO_BERSERK_PENALTY;potion_effect(POT_BERSERK_RAGE, 150);break;}done_good = true;}else if (random2(sever) <= 4){temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Serve the mortal, my children!\"" :(temp_rand == 1) ? "Xom grants you some temporary aid.": "Xom opens a gate.");create_monster( MONS_NEQOXEC + random2(5), 3,BEH_FRIENDLY, you.x_pos, you.y_pos,you.pet_target, 250 );create_monster( MONS_NEQOXEC + random2(5), 3,BEH_FRIENDLY, you.x_pos, you.y_pos,you.pet_target, 250 );if (random2( you.experience_level ) >= 8){create_monster( MONS_NEQOXEC + random2(5), 3,BEH_FRIENDLY, you.x_pos, you.y_pos,you.pet_target, 250 );}if (random2( you.experience_level ) >= 8){create_monster( MONS_HELLION + random2(10), 3,BEH_FRIENDLY, you.x_pos, you.y_pos,you.pet_target, 250 );}if (random2( you.experience_level ) >= 8){create_monster( MONS_HELLION + random2(10), 3,BEH_FRIENDLY, you.x_pos, you.y_pos,you.pet_target, 250 );}done_good = true;}else if (random2(sever) <= 3){temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Take this token of my esteem.\"" :(temp_rand == 1) ? "Xom grants you a gift!": "Xom's generous nature manifests itself.");if (grid_destroys_items(grd[you.x_pos][you.y_pos])) {// How unfortunate. I'll bet Xom feels sorry for you.mprf(MSGCH_SOUND,grid_item_destruction_message(grd[you.x_pos][you.y_pos]));}else{int thing_created = items(1, OBJ_RANDOM, OBJ_RANDOM, true,you.experience_level * 3, 250);move_item_to_grid( &thing_created, you.x_pos, you.y_pos );if (thing_created != NON_ITEM){origin_acquired(mitm[thing_created], GOD_XOM);canned_msg(MSG_SOMETHING_APPEARS);more();}}done_good = true;}else if (random2(sever) <= 4){const int demon = (random2(you.experience_level) < 6)? MONS_WHITE_IMP + random2(5): MONS_NEQOXEC + random2(5);if (create_monster( demon, 0, BEH_FRIENDLY, you.x_pos, you.y_pos,you.pet_target, 250 ) != -1){temp_rand = random2(3);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Serve the mortal, my child!\"" :(temp_rand == 1) ? "Xom grants you a demonic servitor.": "Xom opens a gate.");}else{god_speaks(GOD_XOM, "You hear Xom cackling.");}done_good = true; // well, for Xom, trying == doing {dlb}}else if (random2(sever) <= 4){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"Take this instrument of destruction!\"" :(temp_rand == 1) ? "\"You have earned yourself a gift.\"" :(temp_rand == 2) ? "Xom grants you an implement of death.": "Xom smiles on you.");if (acquirement(OBJ_WEAPONS, GOD_XOM))more();done_good = true;}else if (!you.is_undead && random2(sever) <= 5){temp_rand = random2(4);god_speaks(GOD_XOM,(temp_rand == 0) ? "\"You need some minor adjustments, mortal!\"" :(temp_rand == 1) ? "\"Let me alter your pitiful body.\"" :(temp_rand == 2) ? "Xom's power touches on you for a moment.": "You hear Xom's maniacal chuckling.");mpr("Your body is suffused with distortional energy.");set_hp(1 + random2(you.hp), false);deflate_hp(you.hp_max / 2, true);if (coinflip() || !give_cosmetic_mutation())give_good_mutation();done_good = true;}else if (random2(sever) <= 2){// this should remain the last possible outcome {dlb}if (!one_chance_in(8))you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 1;god_speaks(GOD_XOM, "The area is suffused with divine lightning!");beam.beam_source = NON_MONSTER;beam.type = SYM_BURST;beam.damage = dice_def( 3, 30 );beam.flavour = BEAM_ELECTRICITY;beam.target_x = you.x_pos;beam.target_y = you.y_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;explosion(beam);if (you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] == 1){mpr("Your divine protection wanes.");you.attribute[ATTR_DIVINE_LIGHTNING_PROTECTION] = 0;}done_good = true;}} // end "Good Things"if (done_bad || done_good )return;if ( one_chance_in(4) ) {god_speaks(GOD_XOM, "Xom's attention is distracted from you.");return;}goto okay_try_again;} // end Xom_acts()
{// One in ten chance that Xom might do something good...// but that isn't forced, bad things are thoughbool nice = one_chance_in(10);bool force = !nice;Xom_acts(nice, you.experience_level, force);}
// One in ten chance that Xom might do something good...xom_acts(one_chance_in(10), abs(you.piety - 100));
you.piety = 15; // to prevent near instant excommunicationyou.gift_timeout = 0;
if (you.religion == GOD_XOM){// Xom uses piety and gift_timeout differently.you.piety = 100;you.gift_timeout = random2(40) + random2(40);}else{you.piety = 15; // to prevent near instant excommunicationyou.gift_timeout = 0;}
if (one_chance_in(75))Xom_acts(true, you.experience_level + random2(15), true);
{// Xom semi-randomly drifts your piety.int delta;const char *origfavour = describe_xom_favour();const bool good = you.piety >= 100;int size = abs(you.piety - 100);delta = (random2(1000) < 511) ? 1 : -1;size += delta;you.piety = 100 + (good ? size : -size);const char *newfavour = describe_xom_favour();if (strcmp(origfavour, newfavour)){// Dampen oscillation across announcement boundaries:size += delta * 2;you.piety = 100 + (good ? size : -size);}// ... but he gets bored... (I re-use gift_timeout for// this instead of making a separate field because I don't// want to learn how to save and restore a new field). In// this usage, the "gift" is the gift you give to Xom of// something interesting happening.if (you.gift_timeout == 1){mpr("Xom is getting BORED.");you.gift_timeout = 0;}else if (you.gift_timeout > 1){you.gift_timeout -= random2(2);}if (one_chance_in(20)){// If you.gift_timeout was == 0, then Xom was BORED.// He HATES that.xom_acts(you.gift_timeout > 0 && you.piety > 100,abs(you.piety - 100));}
static void xom_checks_damage(kill_method_type death_type,int dam, int death_source){//if (you.hp <= dam)// xom_is_stimulated(32);if ((death_type != KILLED_BY_MONSTER && death_type != KILLED_BY_BEAM)|| death_source < 0 || death_source >= MAX_MONSTERS){return ;}int amusementvalue = 1;const monsters *monster = &menv[death_source];if (!monster->alive())return;int leveldif = monster->hit_dice - you.experience_level;
if (leveldif == 0)leveldif = 1;/* Note that Xom is amused when you are significantly hurt* by a creature of higher level than yourself as well as* by a creatured of lower level than yourself. */amusementvalue += leveldif * leveldif * dam;if (!player_monster_visible(monster))amusementvalue += 10;if (monster->speed < (int) player_movement_speed())amusementvalue += 8;if (death_type != KILLED_BY_BEAM){if (you.skills[SK_RANGED_COMBAT] <= (you.experience_level / 4))amusementvalue += 2;}else{if (you.skills[SK_FIGHTING] <= (you.experience_level / 4))amusementvalue += 2;}if (player_in_a_dangerous_place())amusementvalue += 2;amusementvalue /= (you.hp > 0) ? you.hp : 1;xom_is_stimulated(amusementvalue);}
mpr( "* * * LOW HITPOINT WARNING * * *", MSGCH_DANGER );
if (Options.hp_warning&& you.hp <= (you.hp_max * Options.hp_warning) / 100){mpr( "* * * LOW HITPOINT WARNING * * *", MSGCH_DANGER );}xom_checks_damage(death_type, dam, death_source);return;
else // you.religion == GOD_MAKHLEB
// the new (piety-aware) Xom uses piety in his own special way...// (namely, 100 is neutral)you.piety = 100;// the new (piety-aware) Xom uses gift_timeout in his own special// way... (namely, a countdown to becoming bored)you.gift_timeout = random2(40) + random2(40);}else // Makhleb{you.piety = 25;
int mutat = which_mutation;bool force_mutation = false; // is mutation forced?bool demonspawn = false; // demonspawn mutation?int i;
int amusement = 16 * (11 - mutation_rarity[which_mutation]);
demonspawn = true;force_mutation = true;mutat -= 2000;which_mutation -= 2000;
case MUT_TOUGH_SKIN:case MUT_STRONG:case MUT_CLEVER:case MUT_AGILE:case MUT_POISON_RESISTANCE:case MUT_TELEPORT_CONTROL:case MUT_MAGIC_RESISTANCE:case MUT_TELEPORT_AT_WILL:case MUT_MAPPING:case MUT_CLARITY:case MUT_MUTATION_RESISTANCE:amusement /= 2; // not funnybreak;case MUT_CARNIVOROUS:case MUT_HERBIVOROUS:case MUT_FAST_METABOLISM:case MUT_WEAK:case MUT_DOPEY:case MUT_CLUMSY:case MUT_TELEPORT:case MUT_FAST:case MUT_DEFORMED:case MUT_SPIT_POISON:case MUT_BREATHE_FLAMES:case MUT_BLINK:case MUT_HORNS:case MUT_LOST:case MUT_BERSERK:case MUT_DETERIORATION:case MUT_BLURRY_VISION:case MUT_FRAIL:case MUT_CLAWS:case MUT_HOOVES:case MUT_BREATHE_POISON:case MUT_STINGER:case MUT_BIG_WINGS:case MUT_BLUE_MARKS:case MUT_GREEN_MARKS:amusement *= 2; // funny!break;default:break;
if (you.mutation[mutat] >= 3&& (mutat != MUT_STRONG && mutat != MUT_CLEVER && mutat != MUT_AGILE)&& (mutat != MUT_WEAK && mutat != MUT_DOPEY && mutat != MUT_CLUMSY))
if (one_chance_in(1000))return false;if (one_chance_in(5)){switch (random2(8)){case 0: mutat = MUT_WEAK; break;case 1: mutat = MUT_DOPEY; break;case 2: mutat = MUT_CLUMSY; break;case 3: mutat = MUT_DEFORMED; break;case 4: mutat = MUT_LOST; break;case 5: mutat = MUT_DETERIORATION; break;case 6: mutat = MUT_BLURRY_VISION; break;case 7: mutat = MUT_FRAIL; break;}}}while ((you.mutation[mutat] >= 3&& (mutat != MUT_STRONG && mutat != MUT_CLEVER&& mutat != MUT_AGILE) && (mutat != MUT_WEAK&& mutat != MUT_DOPEY&& mutat != MUT_CLUMSY))|| you.mutation[mutat] > 13|| random2(10) >= mutation_rarity[mutat] + you.demon_pow[mutat]);}else if (you.mutation[mutat] >= 3&& (mutat != MUT_STRONG && mutat != MUT_CLEVER&& mutat != MUT_AGILE)&& (mutat != MUT_WEAK && mutat != MUT_DOPEY&& mutat != MUT_CLUMSY))
&& (mutat != MUT_STRONG && mutat != MUT_CLEVER && mutat != MUT_AGILE)&& (mutat != MUT_WEAK && mutat != MUT_DOPEY && mutat != MUT_CLUMSY))
&& (mutat != MUT_STRONG && mutat != MUT_CLEVER&& mutat != MUT_AGILE)&& (mutat != MUT_WEAK && mutat != MUT_DOPEY&& mutat != MUT_CLUMSY))
bool give_good_mutation(bool failMsg){int temp_rand = 0; // probability determination {dlb}int which_good_one = 0;temp_rand = random2(25);which_good_one = ((temp_rand >= 24) ? MUT_TOUGH_SKIN :(temp_rand == 23) ? MUT_STRONG :(temp_rand == 22) ? MUT_CLEVER :(temp_rand == 21) ? MUT_AGILE :(temp_rand == 20) ? MUT_HEAT_RESISTANCE :(temp_rand == 19) ? MUT_COLD_RESISTANCE :(temp_rand == 18) ? MUT_SHOCK_RESISTANCE :(temp_rand == 17) ? MUT_REGENERATION :(temp_rand == 16) ? MUT_TELEPORT_CONTROL :(temp_rand == 15) ? MUT_MAGIC_RESISTANCE :(temp_rand == 14) ? MUT_FAST :(temp_rand == 13) ? MUT_ACUTE_VISION :(temp_rand == 12) ? MUT_GREEN_SCALES :(temp_rand == 11) ? MUT_BLACK_SCALES :(temp_rand == 10) ? MUT_GREY_SCALES :(temp_rand == 9) ? MUT_BONEY_PLATES :(temp_rand == 8) ? MUT_REPULSION_FIELD :(temp_rand == 7) ? MUT_POISON_RESISTANCE :(temp_rand == 6) ? MUT_TELEPORT_AT_WILL :(temp_rand == 5) ? MUT_SPIT_POISON :(temp_rand == 4) ? MUT_MAPPING :(temp_rand == 3) ? MUT_BREATHE_FLAMES :(temp_rand == 2) ? MUT_BLINK :(temp_rand == 1) ? MUT_CLARITY: MUT_ROBUST);
// last updated: 08jun2000 {dlb}/* ************************************************************************ called from: beam - effects - monstuff* *********************************************************************** */bool monster_polymorph(struct monsters *monster, int targetc, int power);
enum poly_power_type {PPT_LESS,PPT_MORE,PPT_SAME};bool monster_polymorph(monsters *monster, monster_type targetc,poly_power_type p = PPT_SAME);
// Xom doesn't care who you killed:if (you.religion == GOD_XOM&& random2(70) <= 10 + monster->hit_dice){// postpone Xom action until after the monster diesxom_will_act = 1 + random2(monster->hit_dice);}// Trying to prevent summoning abuse here, so we're trying to
// note that power is (as of yet) unused within this function -// may be worthy of consideration of later implementation, though,// so I'll still let the parameter exist for the time being {dlb}bool monster_polymorph( monsters *monster, int targetc, int power )
static bool is_poly_power_unsuitable(poly_power_type power,int src_pow,int tgt_pow,int relax){switch (power){case PPT_LESS:return (tgt_pow > src_pow - 3 + (relax * 3) / 2)|| (power == PPT_LESS && (tgt_pow < src_pow - (relax / 2)));case PPT_MORE:return (tgt_pow < src_pow + 2 - relax)|| (power == PPT_MORE && (tgt_pow > src_pow + relax));default:case PPT_SAME:return (tgt_pow < src_pow - relax)|| (tgt_pow > src_pow + (relax * 3) / 2);}}/** if targetc == RANDOM_MONSTER then relpower indicates the desired* power of the new monster relative to the current monster.* Relaxation still takes effect when needed no matter what relpower* says.*/bool monster_polymorph( monsters *monster, monster_type targetc,poly_power_type power )
mprf(MSGCH_SOUND, "You hear a splashing noise.");
const bool can_see =mons_near(this) && player_monster_visible(this);if (can_see)mprf("%s splashes around in the water.");else if (!silenced(you.x_pos, you.y_pos) && !silenced(x, y))mprf(MSGCH_SOUND, "You hear a splashing noise.");
}static const char *shop_types[] = {"weapon","armour","antique weapon","antique armour","antiques","jewellery","wand","book","food","distillery","scroll","general"};int str_to_shoptype(const std::string &s){if (s == "random" || s == "any")return (SHOP_RANDOM);for (unsigned i = 0; i < sizeof(shop_types) / sizeof (*shop_types); ++i){if (s == shop_types[i])return (i);}return (-1);}/* Decides whether autoprayer Right Now is a good idea. */static bool should_autopray(){if ( Options.autoprayer_on == false ||you.religion == GOD_NO_GOD ||you.duration[DUR_PRAYER] ||grid_altar_god( grd[you.x_pos][you.y_pos] ) != GOD_NO_GOD ||!i_feel_safe() )return false;// We already know that we're not praying now. So if you// just autoprayed, there's a problem.if ( you.just_autoprayed ){mpr("Autoprayer failed, deactivating.", MSGCH_WARN);Options.autoprayer_on = false;return false;}return true;}/* Actually performs autoprayer. */bool do_autopray(){if ( you.turn_is_over ) // can happen with autopickup, I thinkreturn false;if ( should_autopray() ){pray();you.just_autoprayed = true;return true;}else{you.just_autoprayed = false;return false;}}// general threat = sum_of_logexpervalues_of_nearby_unfriendly_monsters// highest threat = highest_logexpervalue_of_nearby_unfriendly_monstersvoid monster_threat_values(double *general, double *highest){double sum = 0;int highest_xp = -1;monsters *monster = NULL;for (int it = 0; it < MAX_MONSTERS; it++){monster = &menv[it];if (monster->alive() && mons_near(monster) && !mons_friendly(monster)){const int xp = exper_value(monster);const double log_xp = log(xp);sum += log_xp;if (xp > highest_xp){highest_xp = xp;*highest = log_xp;}}}*general = sum;}bool player_in_a_dangerous_place(){const double logexp = log(you.experience);double gen_threat = 0.0, hi_threat = 0.0;monster_threat_values(&gen_threat, &hi_threat);return (gen_threat > logexp * 1.3 || hi_threat > logexp / 2);
}}static const char *shop_types[] = {"weapon","armour","antique weapon","antique armour","antiques","jewellery","wand","book","food","distillery","scroll","general"};int str_to_shoptype(const std::string &s){if (s == "random" || s == "any")return (SHOP_RANDOM);for (unsigned i = 0; i < sizeof(shop_types) / sizeof (*shop_types); ++i){if (s == shop_types[i])return (i);}return (-1);}/* Decides whether autoprayer Right Now is a good idea. */static bool should_autopray(){if ( Options.autoprayer_on == false ||you.religion == GOD_NO_GOD ||you.duration[DUR_PRAYER] ||grid_altar_god( grd[you.x_pos][you.y_pos] ) != GOD_NO_GOD ||!i_feel_safe() )return false;// We already know that we're not praying now. So if you// just autoprayed, there's a problem.if ( you.just_autoprayed ){mpr("Autoprayer failed, deactivating.", MSGCH_WARN);Options.autoprayer_on = false;return false;
mitm[p].sub_type = random2(3);if (random2(35) <= item_level + 10){mitm[p].sub_type = random2(5);if (one_chance_in(4))mitm[p].sub_type = ARM_ANIMAL_SKIN;}if (random2(60) <= item_level + 10)mitm[p].sub_type = random2(8);if (10 + item_level >= random2(400) && one_chance_in(20))mitm[p].sub_type = ARM_DRAGON_HIDE + random2(7);if (10 + item_level >= random2(500) && one_chance_in(20)){mitm[p].sub_type = ARM_STEAM_DRAGON_HIDE + random2(11);if (mitm[p].sub_type == ARM_ANIMAL_SKIN && one_chance_in(20))mitm[p].sub_type = ARM_CRYSTAL_PLATE_MAIL;}// secondary armours:if (one_chance_in(5)){mitm[p].sub_type = ARM_SHIELD + random2(5);if (mitm[p].sub_type == ARM_SHIELD) // 33.3%{if (coinflip())mitm[p].sub_type = ARM_BUCKLER; // 50.0%else if (one_chance_in(3))mitm[p].sub_type = ARM_LARGE_SHIELD; // 16.7%}}
mitm[p].sub_type = get_random_armour_type(item_level);
// Note that acquirement level gold gives much less than the// price of a scroll of acquirement (520 gold). -- bwrif (item_level == MAKE_GOOD_ITEM)quant = 50 + random2avg(100, 2) + random2avg(100, 2);
// Acquirement now gives more gold: The base price of a scroll// of acquirement is 520 gold. The expected value of the gold// it produces is about 480. So you cannot consistently make a// profit by buying scrolls of acquirement. However, there is// a very low chance you'll get lucky and receive up to 2296!// This is quite rare: 50% of the time you'll get less than// 360 gold and 90% of the time you'll get less than 900 and// 99% of the time you'll get less than 1500. --Zookoif (make_good_item)quant = 150 + random2(150) + random2(random2(random2(2000)));
jewellery_type get_random_amulet_type(){return (jewellery_type)(AMU_FIRST_AMULET + random2(NUM_JEWELLERY - AMU_FIRST_AMULET));}static jewellery_type get_raw_random_ring_type(){return (jewellery_type) (RING_REGENERATION + random2(NUM_RINGS));}jewellery_type get_random_ring_type(){const jewellery_type j = get_raw_random_ring_type();// Adjusted distribution here -- bwrif ((j == RING_INVISIBILITY|| j == RING_REGENERATION|| j == RING_TELEPORT_CONTROL|| j == RING_SLAYING)&& !one_chance_in(3)){return get_raw_random_ring_type();}return (j);}armour_type get_random_body_armour_type(int item_level){for (int tries = 100; tries > 0; --tries){const armour_type tr = get_random_armour_type(item_level);if (get_armour_slot(tr) == EQ_BODY_ARMOUR)return (tr);}return (ARM_ROBE);}// FIXME: Need to clean up this mess.armour_type get_random_armour_type(int item_level){int armtype = random2(3);if (random2(35) <= item_level + 10){armtype = random2(5);if (one_chance_in(4))armtype = ARM_ANIMAL_SKIN;}if (random2(60) <= item_level + 10)armtype = random2(8);if (10 + item_level >= random2(400) && one_chance_in(20))armtype = ARM_DRAGON_HIDE + random2(7);if (10 + item_level >= random2(500) && one_chance_in(20)){armtype = ARM_STEAM_DRAGON_HIDE + random2(11);if (armtype == ARM_ANIMAL_SKIN && one_chance_in(20))armtype = ARM_CRYSTAL_PLATE_MAIL;}// secondary armours:if (one_chance_in(5)){armtype = ARM_SHIELD + random2(5);if (armtype == ARM_SHIELD) // 33.3%{if (coinflip())armtype = ARM_BUCKLER; // 50.0%else if (one_chance_in(3))armtype = ARM_LARGE_SHIELD; // 16.7%}}return static_cast<armour_type>(armtype);}
#endif /* #if defined(WIN32CONSOLE) */
#endif /* #if defined(DOS) */
bool item_def::cursed() const{return (item_cursed(*this));}
static std::string describe_favour_generic(god_type which_god){std::string godname = god_name(which_god);return (you.piety > 130) ? "A prized avatar of " + godname + ".":(you.piety > 100) ? "A shining star in the eyes of " + godname + "." :(you.piety > 70) ? "A rising star in the eyes of " + godname + "." :(you.piety > 40) ? godname + " is most pleased with you." :(you.piety > 20) ? godname + " has noted your presence." :(you.piety > 5) ? godname + " is noncommittal.": "You are beneath notice.";}
if (player_under_penance()) //mv: penance check{cprintf( (you.penance[which_god] >= 50) ? "Godly wrath is upon you!" :(you.penance[which_god] >= 20) ? "You've transgressed heavily! Be penitent!" :(you.penance[which_god] >= 5 ) ? "You are under penance.": "You should show more discipline." );}else{if (which_god == GOD_XOM)cprintf("You are ignored.");else{cprintf( (you.piety > 130) ? "A prized avatar of %s.":(you.piety > 100) ? "A shining star in the eyes of %s." :(you.piety > 70) ? "A rising star in the eyes of %s." :(you.piety > 40) ? "%s is most pleased with you." :(you.piety > 20) ? "%s has noted your presence." :(you.piety > 5) ? "%s is noncommittal.": "You are beneath %s's notice.",god_name(which_god));}}//end of favour
cprintf(describe_favour(which_god).c_str());
if (you.religion != GOD_XOM) // Xom doesn't care{text += god_prayer_reaction();text += "\n";}
text += god_prayer_reaction();text += "\n";
// you can swap places with a friendly monster if you// can see it and you're not confusedif (mons_friendly( mon ) && player_monster_visible( mon ) && !you.conf)
// you can swap places with a friendly monster if you're not confusedif (mons_friendly( mon ) && !you.conf)