QAD5QRQDRHBP2SKJXPYAHIJOUUBXQTJEAMJUU274I3UY2WW7FEXQC GBH23XC4IIUSUXO2AWVWZP5SUBIVLH2JEP7BXZQW7JPFQQ356SUAC WJV5GC6EYV5NAVSRHUWT7KDDCC46SGT3ZFNZBAHHK5HVOGAWACCAC UZTXJW3EW3N63K7GSC4EMPGHEHDHBW2P3HMINLGXS4UPGZHRWKLAC 4NDJLMFFC7YF7NARAT64ZBWRE5QEFEOL34KDSHFWFXACI7NE2F4QC SXPQSJIWN6G642ROHGHG22XOOJL2DKJOJIT4MFQFFWFWIP4SG2VAC EPX5ZPJEARQ6Z3DW7M6GMPND3ZNZUN2OWXIJCXVH7TJFZXA2VIZAC VXT2KCTUSBREZLVJGINL2XY2P766DY57W44XTW4KANJH2A4WFPHAC QSUB43KOJG5ZN5JYY2IJ4TGNGVY6LI5OAO6OASYYOMYTGXQWUAYAC H4WYMTARHB33JNRKJGZZYL22RKWTBFLHX2PUC6DQSGZBV6JMIYIAC CQR54KQDXP6KE37UR4V3T4ZI2UKPWYXOUU4D4RASGKOFVGBJGTGQC ZTGL6NBMDI5FA7C3JFLH6DUQNK47EQIOIRKOEYMRCSA7S3TQESIQC 5DVMFDTDCWKGQ372J5WGN4FDYUQWZZV6NJKW4VDD4QLCPZET5L5QC WZ5INX2BYTC3FPVA2SDPX3FGTFWKO27G5GJL62GKSHEYVFAV24GAC G7DNYFW745Q567EF3TPR2FCQ4ATPN236ON7X5TLYC7TEPZW3BAFAC JROZ5XCAQKPXFV242IO3OACFTD6KC4SNSWIXPI5WO4FQ5APRLC4QC E76RRHMXEPJCNDNKMI3AP7OI7IOMXXRHVYWRIYA75BQMMIST2XRAC Y6YXZ7CF7TJ5WIYFGQA7OFF52P3V5YHKTMUOSBIPAFCRCMNPGSZQC RBAGQ2PB7V5YAM5KSHSZR2E3MLKDSRVM5XYGI2TIXP5QMVBOQHDQC K2CS6TCX2NDVL2ASEHGP4J4K4IJ6FP3ANNKTSIWVG43HPYSBX6ZQC QEEJFAETO6B2J4IWDIDCJ5UNIFNNHHG22IWF2CUJRTJJBNE47CWQC SVY2PTCLXR3KNPQAWXVXTTGCC5DR334HOAKHYO3VDDRWM2BWMALAC U6HLBU2OIMKVNWWZ55SERG56WKAW3GSFFEGUJBP4SQVYSESGXC2QC FDMKFGCTWKKSBP3B5VE4BSVFHUVNX5BSDFRVD6E735DHPVYEQFGQC 2XSNHF7JXHEKABVMXDAU25QKFHJHH256GR4WLYAHKSPF4XLBJW4QC NVD2HSEW2ONWNYDDCTOMZZOUP6NG4DCXI4LNYYIY4BQEBDMJQK5AC OFPZBHMZ6DZ6NZ2NJTLRHPEDIQ4FVRASXBTA7TVQKFZ4CIKDDCNAC TJ544OJG4CFFMGMAQ2B7UJT432EIBUV5HOHDAQ7GMKZZKSDBFXZQC IP4STBRVFU5OPNAPM2XZWU77PXHKLOPBW5EGLGB4ZHYNZS7QKTKAC GQQ6ASWTYODIHG7X32JNUUHP5NMOVZJIHWGS3F3MKRYZGAHP6NVQC 5WVUTEZLEZEML54CKPR6GACQBYY3EMVNXMLJOREN6SSEUZGC47AQC UNXGLYIYBZMWR6GX3LRNAA2UPZD7MNBH7TYGYQTTFHPCJRDZXWPQC 27JI3J23EXDY2G4X7NHTFTSHSEUDGDPFOYPG6P53UNSSJP3DDQTAC ODQ7LIJ2UROGGENIORRXZFWII3ZM2N45YD53FKWDQB7LLRXR4PHAC J6ILYHNWEDUHAP44NSA66DYGFXZAD7KKO3PHVG44IWB3KWMMNTHQC PUO3U5MM6BGXC7BO4PKI77KWEOAWOFF3ZYSVDZJBG2XO7JT3II3AC BEPZL7D7JJHJUUDCVLGJRKKWM7NUAC7X2SU5XJMEASE6YTB53P3AC BNRY5YIXLFE2TDNU2JQHWWXJQVWNSEWQ52DU7XUWIT5DZWKGBDDAC L2CVX5VYQC3XVCEADQEWQYQT4IGJIZJM3XAEAVT3GCY3EF7JINUQC ZPINQTMG4J532QWU6RW7534UNC73ZT3Y3WFDDHJQQFJ6P4IXC62AC GGDX26OLH2EBB2ZBJCBIE3UDPHWEMTMSOEJBJIWCBLUK3HEY3PKQC QSSBY2L2FO3QV77ODEFPGZ63NSE7KACQ5SKCH2WGFB7DXKUHT7EQC LM764EO6YIFOKMRXWZ5S4GYZB4BHZQDTEFP7MEVYO4NN4EDOFGNQC SZLYZGHTB6IVHF4NG3Y7UQMRIH5GIBT65NDOOJAHLAELVMKTMSBQC T3R2D5M4YSC6NFZ6YO3AEG4VWORECX72CHUM5UBADV4UPAAZG7WQC VY2RJLJQMUOVIJOYPTA7AEXPURIV3H6VF7O5QQ7LF44ZS36RTFYAC XJZXBPVEV3HQIWKQ5UYSEMQQ26C4N7QYW23ZIIXMUR2I2S73LUYAC FWNNTOEERPUKXPE4OC52UABFZLKIU3O5GRNNLDK4QI4HR2IOU36QC 4GYZYBY7FFORRNPIEFTV4ZM2C7Z6D2KTQOM537ZCC2YBXT2TNSHAC 4LSDVTTNEK7LTLUCGP5SUVXJBUFF457AKWA7CEUQURWXGGLHRGCQC KVMJCPD4RM6YUWIMO4LDHEIB5W62MTOCGBWAEFBHNOUDYLGKXQ3QC QO5ZJWQ3JK3PEGBPTQSAYIPEJEHG2M2KTD74227G5VG7DVXUL3BQC RIGGVFYNCRFDUUCMIAN7SDEOUL4VMMZI6OYXZW72BVNI4WXJQXWQC WXZQJUZXMYS7R6ORNB7DWE5KEUXT262GXWMRPOJYYB4I3BFGYLLAC JEWRZ3AI42QDS32KLPVYQZIXLS3GYOOU64IR4IPPKZNF4JYUL7TAC 5FMXUX2ZFIF6NQZCS54W7ZOCVSH7XR6UIMQ5FW2UZLEN4EWP5PSAC R6OIKZAWLEAS6COYSOHY37CINPIOTSOVJ5OLJISPUCP64IJAGSGQC FW3PIRSTFPX7VNUAVASCBB7VPYJHGPRSHXC4S6RXCLSLJMGWS6QQC 62CWUC7WKYRODVOOUFHRPDZXGTBUIU7XPR3EHJWESPG2XVUM7SDAC 2KJ6VEN4TXT3L77WRJJ2ZU2QSJV73YQDPJD4WI7UCMSRXXILXHSAC S34LKQDIQJLIWVIPASOJBBZ6ZCXDHP5KPS7TRBZJSCDRVNCLK6UAC V4F3SDV2H4HBH6G6W5M3REN3BDSSE4IDF2RNM7PJMKRW3IDJ7PNAC VIQYG6MPI5YOCGDYTUNKGC7SUTNDRMWKT463CHZARVZXQIABGWKAC V4DWL5WBO2JCODVS5QQNWXDH4DAYZN3D5V3UDCHM2KKOMADOTEDQC WZNB427K3EUNV3FMVXLQTM4UIHER4FIKQXWLUUXRNQC3OQ33VQYAC WNDCC2WZEUQ2SHRQZUAAK3A4QF5JGLDJ5D3WLKLNXYSCK4TZ7KZAC B3HWU2BEQQ4E6WKVTW3JQQJFMWTVW3XWKY6BHFNBRHSZPRCF2OTQC IQGGFC563RBS7GDOACKCLXK752EE5RC3T6G5L6H446SXTMSA7T2AC 43IJZIJEQREN63MUKMO2WB5SJI4AXVVA4HORZPMOAFEATHCUHS6AC AXRXY7RSEN3QHQRK6SFEH2OZAAYJRR5RBBBFF4YJF756V2FPFJ3AC XDHIIBQZLHLXAHIPJMXWH3FJ2X5PO7IB7HXQMVZDWM5JZFAG3HAQC FS4MVTH4EEEECLEAO2FTNK5CLF2PHFYO2JZHC2YEOKYLWXRDRU6AC C7Q5QY7S5TTMJ3XO2SIO3FY5ZENWYYETS4NKEKCAJMENEHJC6Y2AC NFXK75IVZIF2JRTVQYLSR7NRD3OV4H24EZT33OBOIDGYYBNJGCKQC MDFQRJ6QZNFUBVSFWLXUJ6EBXOU47T3CVDI2XKBGNNRF4DXDKESQC KYVZGUJXV23ELA4CKPVQZO3NTJCODXMCWYAZJYWVWJVLPETNHLGQC JBZ7NU4BB5PGQWCOSZHD5OQUHQIVOD4XGJLSJQ7BUGQEGPRTVGZQC 3DQXSE4YGFBBDUWK4YEOFWW4UPWILWELFSLP37SL6BERGAZJC5YAC H7GMWXGBKDNFSKIDR5IWTS6UYPRHPBBSAFMVXHZQOZTCZ7OMNVKQC TGJZXTUIAKCFZQJ54ZQEBGFBVZSJCAX6AWDRSH3TP7UJRLGUM5SAC P2OYYNPHIBGOLT4CRLNTTIXDN34EU2QCMFQJNLAMUAHQXZTEDPXQC IGNQ3YSGMW6NG7GPYYXWXW6XPM4YWKNUJ5IU55QCWZ2AEHHO3L3QC KZ362RP6C7HRFQB66QL3PBRG7MBEPLRKTFMJYK7DFJQKERFGNFXQC BWHU47MJ7KAVKMKMRBVYLOHUCASSNVCGPC3SPMNBAC7DLI6XX2YQC 5PNVRKZFGGUKPYADIXIJSBTBGX26NDGSNGYS6WGSBP3JGT5NCCKAC SS6MUIJYTGIVBYU356Z563QJWLJ47QNHSJWS7GJTS7EATZH2ESJQC CQ24AVAI6SW3AHTIDMLPSTRRBEU6FHRF5I5FD6G5QIYE6PO4BQMQC 2RJUPYKEDZZCW4GDG6WLEDVYF32ADC4W5I42KSKHN3MWEBCWSAHQC VVMQW3SQYNMFSMLK7WAXWOXOEDLFLN6W44UOVIJMBMF5AOPYM6FQC TNKSIEURZ6WZTNL5XYNWFENONDAPHJY6VYUHH2AGUGV2WXCEISAAC 6KCBR34M2QLZOQ6WQC4L6Z2MCH4DFV5BZ4QRGQSYRQLKG7WZGHFAC 4I62MHXSS7OWDF2QU7AYXCRB2ZAGHNCZQN24MENLXJFRSGMXXFLAC EODUVLUYJAJFRQAKFIMDYCOI4666SL2JHJDH3NWS452WNCVOI7LAC SDK3Q2BC3R4WJ2TJTJQTAKF6XYBAS2S44C6RZE3FCRMK2UEBDOVAC MG2J6HQGH4DWFH3PC2SZB45NGKK5ISPBADQD24GWAZCZTDLOA33AC BR6HF3PWCXUG24OBIWTCZ64DDVBA2G6BQBDJ5V5WMARRQBG2CLGQC RMZCWOVH2IPIOCGCS7EQQIO7Y5HQ3XPY52K2B6SAPWKYYSJ6EUIAC 3PPH2RAOMAQGDPQKUKMMA3RC5M3VUSEJ7WKGZNVJ7UBFE75K574QC XII3RPTU6PPAY7U7TE4MTVPSOFZTOPF7ZKHMBGG2GHLAWPUFOKCQC JXO53C3SJ5KPLXVEBFGFWCBI4EFY6TCA6QQVH5NII5NP5BC4EWUAC MG6LLF3XYCOEBQRX7TJ4MUTKM3IROYWUMZGCMYVW4TGDG36CJMJQC NLQNXH3SVJ52CWXEV35FSSZP32VHC4QFGN3HINF4KO5GZHZMOBKQC L5YS6SNTQW7YRR5LGCDSLHLNFJ73IWHU4A7S3MY6KYLG67N2KPGAC 5JS3QSE3EIXSBVI4DATH2EIFD7QN3POAFEUM7MK4NRMPH5JOPAAQC F7QFSXE22UPQTBLYJLY26HJ3QPHFNBJMUOFJRV35R5YCHSGKTBYQC PJWXE2ZLK4YCJM77CENEMB5XKVFTXFPMJEWC3TAMOTPZ5HSD3JZAC KNW37MRIU72X4LPXSA4AUPW3VJMOXKWY2XFTV67KW2ZXTCSYMMNAC 5YQ53FYWPSONG3EOUAEMII2ECVAO6SRDUBVICH7JFGFS2Q5L4HYQC 4SWAT5KCKQV527NKELAXFQ5XA4Q5HONQXD4VBXMUZNPVPQKPCPNAC NNQPJEMQAJC6V45OOHEX7OA54DE5IEQI73SJTS5O6PPU3KMHF4WQC EMOBSWJHHB4V6WVMZL7JCF2V3KZN454Z6NS346OKFPMBNO24EJDQC LYEMFS2OCCXSYOZKIQURQDXL64CB5BFP2P3MW3JDCEUIYVWX745QC TR6F3WVSL6TS5SZVGJBGDK54FKAXYWRWXFRNMQ2AYYKHADSHR2EQC FZ3VCF24YWNHTLVHBZYWX37X4FI2SNCXGZGTV2UFGFGAWMOKFIUAC PC6K5OQF3BWPMWTIN5JXAKHTZF453JQOELDWRUOSBZXR256FTUYQC SIDH2P7NBIG5KEOE27XHD3ZT2NQ2OJZFN6VZXWNWYFFY5YVXSSVQC 6UEKO6GLZNCAGVJRMRBVX6XSLS7H3SFUOUZRPECEOA5TV2DC2QIQC RT4UZQXFGZCMWEP553GYPQKMYIKQHRJO7EZ73N76HJI45AW5O3DQC RPOZZWKG5GLPHVZZ7ZKMKS64ZMV2LDCQSARBJFJ6FZOTOKCQO7FAC R22TTMI6WXWULC7ODKFF3QCB7MOTETQQ6IR4BUCUPOCQKQNCTT5AC SDLKLUNFGVKDS55DDJZCBAVIB7NL3RRYPTACAY65SCUQKV6APFSAC 43ZTEB57FU7KE5EVMYWZONNVJBZCGF3JEAJZIY25LC4LGE65PG5QC PR42BCP5BPRFD2MP5H6CIJP7E57Q6TKL6SOXZWFKMFVR2OZWHT7AC BK6MGPSEAEMU4URBAPKY3VTKK6JC6IZVN5CNOSN2UPTIOWQYEWLQC TV3ZC6WOZKSQQJQN26JIVKCHK6UK7WMDBYZDUYRWEAZ4JB4YVNAAC 7AMQN7MITMXBNVDAK5VOXTQ4TZIAOD6ZLOFJG7GQMBTY23Y2BKSAC MQ62OAMLGJVRW2QIL4PAZRAU6PC52ZVGY2FCOBIY6IWGQIHMU5CAC UL7XFKMUX3WIU4O2LZANK4ECJ654UZPDBFGNXUEYZYOLKBYBCG6AC bool zin_sustenance(bool actual = true);bool zin_remove_all_mutations();bool yred_injury_mirror(bool actual = true);bool jiyva_grant_jelly(bool actual = true);bool jiyva_remove_bad_mutation();
void yred_make_enslaved_soul(monsters *mon, bool force_hostile = false,bool quiet = false, bool unrestricted = false);void beogh_convert_orc(monsters *orc, bool emergency,bool converted_by_follower = false);void jiyva_convert_slime(monsters* slime);void feawn_neutralise_plant(monsters *plant);bool feawn_passthrough(const monsters * target);
bool vehumet_supports_spell(spell_type spell);bool trog_burn_spellbooks();
}bool yred_injury_mirror(bool actual){return (you.religion == GOD_YREDELEMNUL && !player_under_penance()&& you.piety >= piety_breakpoint(1)&& (!actual || you.duration[DUR_PRAYER]));
bool beogh_water_walk(){return (you.religion == GOD_BEOGH && !player_under_penance()&& you.piety >= piety_breakpoint(4));}
bool jiyva_remove_bad_mutation(){if (!how_mutated()){mpr("You have no bad mutations to be cured!");return (false);}// Ensure that only bad mutations are removed.if (!delete_mutation(RANDOM_BAD_MUTATION, true, false, true, true)){canned_msg(MSG_NOTHING_HAPPENS);return (false);}mpr("You feel cleansed.");return (true);}
return (true);return (false);}bool vehumet_supports_spell(spell_type spell){if (spell_typematch(spell, SPTYP_CONJURATION | SPTYP_SUMMONING))return (true);if (spell == SPELL_SHATTER|| spell == SPELL_FRAGMENTATION|| spell == SPELL_SANDBLAST){
}// Returns false if the invocation fails (no spellbooks in sight, etc.).bool trog_burn_spellbooks(){if (you.religion != GOD_TROG)return (false);god_acting gdact;for (stack_iterator si(you.pos()); si; ++si){if (si->base_type == OBJ_BOOKS&& si->sub_type != BOOK_MANUAL&& si->sub_type != BOOK_DESTRUCTION){mpr("Burning your own feet might not be such a smart idea!");return (false);}}int totalpiety = 0;for (radius_iterator ri(you.pos(), LOS_RADIUS, true, true, true); ri; ++ri){// If a grid is blocked, books lying there will be ignored.// Allow bombing of monsters.const unsigned short cloud = env.cgrid(*ri);if (feat_is_solid(grd(*ri))|| cloud != EMPTY_CLOUD && env.cloud[cloud].type != CLOUD_FIRE){continue;}int count = 0;int rarity = 0;for (stack_iterator si(*ri); si; ++si){if (si->base_type != OBJ_BOOKS|| si->sub_type == BOOK_MANUAL|| si->sub_type == BOOK_DESTRUCTION){continue;}// Ignore {!D} inscribed books.if (!check_warning_inscriptions(*si, OPER_DESTROY)){mpr("Won't ignite {!D} inscribed book.");continue;}rarity += book_rarity(si->sub_type);// Piety increases by 2 for books never cracked open, else 1.// Conversely, rarity influences the duration of the pyre.if (!item_type_known(*si))totalpiety += 2;elsetotalpiety++;#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Burned book rarity: %d", rarity);#endifdestroy_item(si.link());count++;}if (count){if (cloud != EMPTY_CLOUD){// Reinforce the cloud.mpr("The fire roars with new energy!");const int extra_dur = count + random2(rarity / 2);env.cloud[cloud].decay += extra_dur * 5;env.cloud[cloud].set_whose(KC_YOU);continue;}const int duration = std::min(4 + count + random2(rarity/2), 23);place_cloud(CLOUD_FIRE, *ri, duration, KC_YOU);mprf(MSGCH_GOD, "The book%s burst%s into flames.",count == 1 ? "" : "s",count == 1 ? "s" : "");}}if (!totalpiety){mpr("You cannot see a spellbook to ignite!");return (false);}else{simple_god_message(" is delighted!", GOD_TROG);gain_piety(totalpiety);}return (true);
}static bool _yred_enslaved_souls_on_level_disappear(){bool success = false;for (int i = 0; i < MAX_MONSTERS; ++i){monsters *monster = &menv[i];if (_is_yred_enslaved_soul(monster)){#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Undead soul disappearing: %s on level %d, branch %d",monster->name(DESC_PLAIN).c_str(),static_cast<int>(you.your_level),static_cast<int>(you.where_are_you));#endifsimple_monster_message(monster, " is freed.");// The monster disappears.monster_die(monster, KILL_DISMISSED, NON_MONSTER);success = true;}}return (success);
}void yred_make_enslaved_soul(monsters *mon, bool force_hostile,bool quiet, bool unrestricted){if (!unrestricted)_yred_souls_disappear();const int type = mon->type;monster_type soul_type = mons_species(type);const std::string whose =you.can_see(mon) ? apostrophise(mon->name(DESC_CAP_THE)): mon->pronoun(PRONOUN_CAP_POSSESSIVE);const bool twisted =!unrestricted ? !x_chance_in_y(you.skills[SK_INVOCATIONS] * 20 / 9 + 20,100): false;int corps = -1;// If the monster's held in a net, get it out.mons_clear_trapping_net(mon);const monsters orig = *mon;if (twisted){mon->type = mons_zombie_size(soul_type) == Z_BIG ?MONS_ABOMINATION_LARGE : MONS_ABOMINATION_SMALL;mon->base_monster = MONS_PROGRAM_BUG;}else{// Drop the monster's corpse, so that it can be properly// re-equipped below.corps = place_monster_corpse(mon, true, true);}// Drop the monster's equipment.monster_drop_ething(mon);// Recreate the monster as an abomination, or as itself before// turning it into a spectral thing below.define_monster(*mon);mon->colour = ETC_UNHOLY;mon->flags |= MF_CREATED_FRIENDLY;mon->flags |= MF_ENSLAVED_SOUL;if (twisted)// Mark abominations as undead.mon->flags |= MF_HONORARY_UNDEAD;else if (corps != -1){// Turn the monster into a spectral thing, minus the usual// adjustments for zombified monsters.mon->type = MONS_SPECTRAL_THING;mon->base_monster = soul_type;// Re-equip the spectral thing.equip_undead(mon->pos(), corps, monster_index(mon),mon->base_monster);// Destroy the monster's corpse, as it's no longer needed.destroy_item(corps);}name_zombie(mon, &orig);mons_make_god_gift(mon, GOD_YREDELEMNUL);mon->attitude = !force_hostile ? ATT_FRIENDLY : ATT_HOSTILE;behaviour_event(mon, ME_ALERT, !force_hostile ? MHITNOT : MHITYOU);if (!quiet){mprf("%s soul %s, and %s.", whose.c_str(),twisted ? "becomes twisted" : "remains intact",!force_hostile ? "is now yours" : "fights you");}}static void _print_converted_orc_speech(const std::string key,monsters *mon,msg_channel_type channel){std::string msg = getSpeakString("beogh_converted_orc_" + key);if (!msg.empty()){msg = do_mon_str_replacements(msg, mon);mpr(msg.c_str(), channel);}}// Orcs may turn friendly when encountering followers of Beogh, and be// made gifts of Beogh.void beogh_convert_orc(monsters *orc, bool emergency,bool converted_by_follower){ASSERT(mons_species(orc->type) == MONS_ORC);if (you.can_see(orc)) // show reaction{if (emergency || !orc->alive()){if (converted_by_follower){_print_converted_orc_speech("reaction_battle_follower", orc,MSGCH_FRIEND_ENCHANT);_print_converted_orc_speech("speech_battle_follower", orc,MSGCH_TALK);}else{_print_converted_orc_speech("reaction_battle", orc,MSGCH_FRIEND_ENCHANT);_print_converted_orc_speech("speech_battle", orc, MSGCH_TALK);}}else{_print_converted_orc_speech("reaction_sight", orc,MSGCH_FRIEND_ENCHANT);if (!one_chance_in(3))_print_converted_orc_speech("speech_sight", orc, MSGCH_TALK);}}orc->attitude = ATT_FRIENDLY;// The monster is not really *created* friendly, but should it// become hostile later on, it won't count as a good kill.orc->flags |= MF_CREATED_FRIENDLY;// Prevent assertion if the orc was previously worshipping a// different god, rather than already worshipping Beogh or being an// atheist.orc->god = GOD_NO_GOD;mons_make_god_gift(orc, GOD_BEOGH);if (orc->is_patrolling()){// Make orcs stop patrolling and forget their patrol point,// they're supposed to follow you now.orc->patrol_point = coord_def(0, 0);}if (!orc->alive())orc->hit_points = std::min(random_range(1, 4), orc->max_hit_points);// Avoid immobile "followers".behaviour_event(orc, ME_ALERT, MHITNOT);}void feawn_neutralise_plant(monsters *plant){if (!plant|| !feawn_neutralises(plant)|| plant->attitude != ATT_HOSTILE|| testbits(plant->flags, MF_ATT_CHANGE_ATTEMPT)){return;}plant->attitude = ATT_GOOD_NEUTRAL;plant->flags |= MF_WAS_NEUTRAL;}// During prayer feawn allows worshipers to walk on top of stationary plants// and fungi.bool feawn_passthrough(const monsters * target){return (target && you.religion == GOD_FEAWN&& you.duration[DUR_PRAYER]&& mons_is_plant(target)&& mons_is_stationary(target));
if (you.can_see(slime)){if (mons_genus(slime->type) == MONS_GIANT_EYEBALL){mprf(MSGCH_GOD, "%s stares at you suspiciously for a moment, ""then relaxes.",slime->name(DESC_CAP_THE).c_str());}else{mprf(MSGCH_GOD, "%s trembles before you.",slime->name(DESC_CAP_THE).c_str());}}slime->attitude = ATT_STRICT_NEUTRAL;slime->flags |= MF_WAS_NEUTRAL;if (!mons_eats_items(slime)){slime->add_ench(ENCH_EAT_ITEMS);mprf(MSGCH_MONSTER_ENCHANT, "%s looks hungrier.",slime->name(DESC_CAP_THE).c_str());}// Prevent assertion if the slime was previously worshipping a// different god, rather than already worshipping Jiyva or being an// atheist.slime->god = GOD_NO_GOD;mons_make_god_gift(slime, GOD_JIYVA);}
}bool ponderousify_armour(){int item_slot = -1;do{if (item_slot == -1){item_slot = prompt_invent_item("Make which item ponderous?",MT_INVLIST, OSEL_ENCH_ARM, true, true, false);}if (prompt_failed(item_slot))return (false);item_def& arm(you.inv[item_slot]);if (!is_enchantable_armour(arm, true, true)|| get_armour_ego_type(arm) != SPARM_NORMAL){mpr("Choose some type of armour to enchant, or Esc to abort.");if (Options.auto_list)more();item_slot = -1;mpr("You can't enchant that."); //does not appearcontinue;}//make item desc runed if desc was vanilla?set_item_ego_type(arm, OBJ_ARMOUR, SPARM_PONDEROUSNESS);you.redraw_armour_class = true;you.redraw_evasion = true;simple_god_message(" says: Dude, use this wisely!");return (true);}while (true);return true;
static int _slouch_monsters(coord_def where, int pow, int, actor* agent){monsters* mon = monster_at(where);if (mon == NULL)return (0);int dmg = (mon->speed - player_movement_speed());dmg = (dmg > 0 ? dmg * dmg : 0);mon->hurt(agent, dmg, BEAM_MMISSILE, true);return (1);}int chronos_slouch(int pow){return (apply_area_visible(_slouch_monsters, pow));}
/** File: godabil.h* Summary: God-granted abilities.*/#ifndef GODABIL_H#define GODABILN_H#include "enum.h"#include "externs.h"bool ponderousify_armour();int chronos_slouch(int);bool zin_sustenance(bool actual = true);bool zin_remove_all_mutations();bool yred_injury_mirror(bool actual = true);bool jiyva_grant_jelly(bool actual = true);bool jiyva_remove_bad_mutation();bool beogh_water_walk();void yred_make_enslaved_soul(monsters *mon, bool force_hostile = false,bool quiet = false, bool unrestricted = false);void beogh_convert_orc(monsters *orc, bool emergency,bool converted_by_follower = false);void jiyva_convert_slime(monsters* slime);void feawn_neutralise_plant(monsters *plant);bool feawn_passthrough(const monsters * target);bool vehumet_supports_spell(spell_type spell);bool trog_burn_spellbooks();#endif
/** File: godabil.cc* Summary: God-granted abilities.*/#include "AppHdr.h"#include "cloud.h"#include "database.h"#include "files.h"#include "godabil.h"#include "invent.h"#include "items.h"#include "kills.h"#include "message.h"#include "mon-util.h"#include "monstuff.h"#include "mstuff2.h"#include "mutation.h"#include "religion.h"#include "shopping.h"#include "spells3.h"#include "spl-book.h"#include "spl-util.h"#include "stuff.h"#include "terrain.h"#include "view.h"bool yred_injury_mirror(bool actual){return (you.religion == GOD_YREDELEMNUL && !player_under_penance()&& you.piety >= piety_breakpoint(1)&& (!actual || you.duration[DUR_PRAYER]));}bool beogh_water_walk(){return (you.religion == GOD_BEOGH && !player_under_penance()&& you.piety >= piety_breakpoint(4));}bool jiyva_grant_jelly(bool actual){return (you.religion == GOD_JIYVA && !player_under_penance()&& you.piety >= piety_breakpoint(2)&& (!actual || you.duration[DUR_PRAYER]));}bool jiyva_remove_bad_mutation(){if (!how_mutated()){mpr("You have no bad mutations to be cured!");return (false);}// Ensure that only bad mutations are removed.if (!delete_mutation(RANDOM_BAD_MUTATION, true, false, true, true)){canned_msg(MSG_NOTHING_HAPPENS);return (false);}mpr("You feel cleansed.");return (true);}bool vehumet_supports_spell(spell_type spell){if (spell_typematch(spell, SPTYP_CONJURATION | SPTYP_SUMMONING))return (true);if (spell == SPELL_SHATTER|| spell == SPELL_FRAGMENTATION|| spell == SPELL_SANDBLAST){return (true);}return (false);}// Returns false if the invocation fails (no spellbooks in sight, etc.).bool trog_burn_spellbooks(){if (you.religion != GOD_TROG)return (false);god_acting gdact;for (stack_iterator si(you.pos()); si; ++si){if (si->base_type == OBJ_BOOKS&& si->sub_type != BOOK_MANUAL&& si->sub_type != BOOK_DESTRUCTION){mpr("Burning your own feet might not be such a smart idea!");return (false);}}int totalpiety = 0;for (radius_iterator ri(you.pos(), LOS_RADIUS, true, true, true); ri; ++ri){// If a grid is blocked, books lying there will be ignored.// Allow bombing of monsters.const unsigned short cloud = env.cgrid(*ri);if (feat_is_solid(grd(*ri))|| cloud != EMPTY_CLOUD && env.cloud[cloud].type != CLOUD_FIRE){continue;}int count = 0;int rarity = 0;for (stack_iterator si(*ri); si; ++si){if (si->base_type != OBJ_BOOKS|| si->sub_type == BOOK_MANUAL|| si->sub_type == BOOK_DESTRUCTION){continue;}// Ignore {!D} inscribed books.if (!check_warning_inscriptions(*si, OPER_DESTROY)){mpr("Won't ignite {!D} inscribed book.");continue;}rarity += book_rarity(si->sub_type);// Piety increases by 2 for books never cracked open, else 1.// Conversely, rarity influences the duration of the pyre.if (!item_type_known(*si))totalpiety += 2;elsetotalpiety++;#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Burned book rarity: %d", rarity);#endifdestroy_item(si.link());count++;}if (count){if (cloud != EMPTY_CLOUD){// Reinforce the cloud.mpr("The fire roars with new energy!");const int extra_dur = count + random2(rarity / 2);env.cloud[cloud].decay += extra_dur * 5;env.cloud[cloud].set_whose(KC_YOU);continue;}const int duration = std::min(4 + count + random2(rarity/2), 23);place_cloud(CLOUD_FIRE, *ri, duration, KC_YOU);mprf(MSGCH_GOD, "The book%s burst%s into flames.",count == 1 ? "" : "s",count == 1 ? "s" : "");}}if (!totalpiety){mpr("You cannot see a spellbook to ignite!");return (false);}else{simple_god_message(" is delighted!", GOD_TROG);gain_piety(totalpiety);}return (true);}static bool _is_yred_enslaved_soul(const monsters* mon){return (mon->alive() && mons_enslaved_soul(mon));}static bool _yred_enslaved_souls_on_level_disappear(){bool success = false;for (int i = 0; i < MAX_MONSTERS; ++i){monsters *monster = &menv[i];if (_is_yred_enslaved_soul(monster)){#ifdef DEBUG_DIAGNOSTICSmprf(MSGCH_DIAGNOSTICS, "Undead soul disappearing: %s on level %d, branch %d",monster->name(DESC_PLAIN).c_str(),static_cast<int>(you.your_level),static_cast<int>(you.where_are_you));#endifsimple_monster_message(monster, " is freed.");// The monster disappears.monster_die(monster, KILL_DISMISSED, NON_MONSTER);success = true;}}return (success);}static bool _yred_souls_disappear(){return (apply_to_all_dungeons(_yred_enslaved_souls_on_level_disappear));}void yred_make_enslaved_soul(monsters *mon, bool force_hostile,bool quiet, bool unrestricted){if (!unrestricted)_yred_souls_disappear();const int type = mon->type;monster_type soul_type = mons_species(type);const std::string whose =you.can_see(mon) ? apostrophise(mon->name(DESC_CAP_THE)): mon->pronoun(PRONOUN_CAP_POSSESSIVE);const bool twisted =!unrestricted ? !x_chance_in_y(you.skills[SK_INVOCATIONS] * 20 / 9 + 20,100): false;int corps = -1;// If the monster's held in a net, get it out.mons_clear_trapping_net(mon);const monsters orig = *mon;if (twisted){mon->type = mons_zombie_size(soul_type) == Z_BIG ?MONS_ABOMINATION_LARGE : MONS_ABOMINATION_SMALL;mon->base_monster = MONS_PROGRAM_BUG;}else{// Drop the monster's corpse, so that it can be properly// re-equipped below.corps = place_monster_corpse(mon, true, true);}// Drop the monster's equipment.monster_drop_ething(mon);// Recreate the monster as an abomination, or as itself before// turning it into a spectral thing below.define_monster(*mon);mon->colour = ETC_UNHOLY;mon->flags |= MF_CREATED_FRIENDLY;mon->flags |= MF_ENSLAVED_SOUL;if (twisted)// Mark abominations as undead.mon->flags |= MF_HONORARY_UNDEAD;else if (corps != -1){// Turn the monster into a spectral thing, minus the usual// adjustments for zombified monsters.mon->type = MONS_SPECTRAL_THING;mon->base_monster = soul_type;// Re-equip the spectral thing.equip_undead(mon->pos(), corps, monster_index(mon),mon->base_monster);// Destroy the monster's corpse, as it's no longer needed.destroy_item(corps);}name_zombie(mon, &orig);mons_make_god_gift(mon, GOD_YREDELEMNUL);mon->attitude = !force_hostile ? ATT_FRIENDLY : ATT_HOSTILE;behaviour_event(mon, ME_ALERT, !force_hostile ? MHITNOT : MHITYOU);if (!quiet){mprf("%s soul %s, and %s.", whose.c_str(),twisted ? "becomes twisted" : "remains intact",!force_hostile ? "is now yours" : "fights you");}}static void _print_converted_orc_speech(const std::string key,monsters *mon,msg_channel_type channel){std::string msg = getSpeakString("beogh_converted_orc_" + key);if (!msg.empty()){msg = do_mon_str_replacements(msg, mon);mpr(msg.c_str(), channel);}}// Orcs may turn friendly when encountering followers of Beogh, and be// made gifts of Beogh.void beogh_convert_orc(monsters *orc, bool emergency,bool converted_by_follower){ASSERT(mons_species(orc->type) == MONS_ORC);if (you.can_see(orc)) // show reaction{if (emergency || !orc->alive()){if (converted_by_follower){_print_converted_orc_speech("reaction_battle_follower", orc,MSGCH_FRIEND_ENCHANT);_print_converted_orc_speech("speech_battle_follower", orc,MSGCH_TALK);}else{_print_converted_orc_speech("reaction_battle", orc,MSGCH_FRIEND_ENCHANT);_print_converted_orc_speech("speech_battle", orc, MSGCH_TALK);}}else{_print_converted_orc_speech("reaction_sight", orc,MSGCH_FRIEND_ENCHANT);if (!one_chance_in(3))_print_converted_orc_speech("speech_sight", orc, MSGCH_TALK);}}orc->attitude = ATT_FRIENDLY;// The monster is not really *created* friendly, but should it// become hostile later on, it won't count as a good kill.orc->flags |= MF_CREATED_FRIENDLY;// Prevent assertion if the orc was previously worshipping a// different god, rather than already worshipping Beogh or being an// atheist.orc->god = GOD_NO_GOD;mons_make_god_gift(orc, GOD_BEOGH);if (orc->is_patrolling()){// Make orcs stop patrolling and forget their patrol point,// they're supposed to follow you now.orc->patrol_point = coord_def(0, 0);}if (!orc->alive())orc->hit_points = std::min(random_range(1, 4), orc->max_hit_points);// Avoid immobile "followers".behaviour_event(orc, ME_ALERT, MHITNOT);}void feawn_neutralise_plant(monsters *plant){if (!plant|| !feawn_neutralises(plant)|| plant->attitude != ATT_HOSTILE|| testbits(plant->flags, MF_ATT_CHANGE_ATTEMPT)){return;}plant->attitude = ATT_GOOD_NEUTRAL;plant->flags |= MF_WAS_NEUTRAL;}// During prayer feawn allows worshipers to walk on top of stationary plants// and fungi.bool feawn_passthrough(const monsters * target){return (target && you.religion == GOD_FEAWN&& you.duration[DUR_PRAYER]&& mons_is_plant(target)&& mons_is_stationary(target));}void jiyva_convert_slime(monsters* slime){ASSERT(mons_is_slime(slime));if (you.can_see(slime)){if (mons_genus(slime->type) == MONS_GIANT_EYEBALL){mprf(MSGCH_GOD, "%s stares at you suspiciously for a moment, ""then relaxes.",slime->name(DESC_CAP_THE).c_str());}else{mprf(MSGCH_GOD, "%s trembles before you.",slime->name(DESC_CAP_THE).c_str());}}slime->attitude = ATT_STRICT_NEUTRAL;slime->flags |= MF_WAS_NEUTRAL;if (!mons_eats_items(slime)){slime->add_ench(ENCH_EAT_ITEMS);mprf(MSGCH_MONSTER_ENCHANT, "%s looks hungrier.",slime->name(DESC_CAP_THE).c_str());}// Prevent assertion if the slime was previously worshipping a// different god, rather than already worshipping Jiyva or being an// atheist.slime->god = GOD_NO_GOD;mons_make_god_gift(slime, GOD_JIYVA);}bool ponderousify_armour(){int item_slot = -1;do{if (item_slot == -1){item_slot = prompt_invent_item("Make which item ponderous?",MT_INVLIST, OSEL_ENCH_ARM, true, true, false);}if (prompt_failed(item_slot))return (false);item_def& arm(you.inv[item_slot]);if (!is_enchantable_armour(arm, true, true)|| get_armour_ego_type(arm) != SPARM_NORMAL){mpr("Choose some type of armour to enchant, or Esc to abort.");if (Options.auto_list)more();item_slot = -1;mpr("You can't enchant that."); //does not appearcontinue;}//make item desc runed if desc was vanilla?set_item_ego_type(arm, OBJ_ARMOUR, SPARM_PONDEROUSNESS);you.redraw_armour_class = true;you.redraw_evasion = true;simple_god_message(" says: Dude, use this wisely!");return (true);}while (true);return true;}static int _slouch_monsters(coord_def where, int pow, int, actor* agent){monsters* mon = monster_at(where);if (mon == NULL)return (0);int dmg = (mon->speed - player_movement_speed());dmg = (dmg > 0 ? dmg * dmg : 0);mon->hurt(agent, dmg, BEAM_MMISSILE, true);return (1);}int chronos_slouch(int pow){return (apply_area_visible(_slouch_monsters, pow));}